惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
Security Archives - TechRepublic
Security Archives - TechRepublic
V
Vulnerabilities – Threatpost
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
G
GRAHAM CLULEY
P
Privacy International News Feed
The Hacker News
The Hacker News
Forbes - Security
Forbes - Security
U
Unit 42
N
News and Events Feed by Topic
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
A
About on SuperTechFans
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
D
Docker
I
Intezer
Spread Privacy
Spread Privacy
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术
S
Security @ Cisco Blogs
F
Full Disclosure
S
Secure Thoughts
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
W
WeLiveSecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Project Zero
Project Zero
Recorded Future
Recorded Future
Cyberwarzone
Cyberwarzone
S
Security Affairs
AWS News Blog
AWS News Blog
H
Help Net Security
The GitHub Blog
The GitHub Blog
Hacker News: Ask HN
Hacker News: Ask HN
Vercel News
Vercel News
P
Proofpoint News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Register - Security
The Register - Security
S
Schneier on Security
F
Fortinet All Blogs
C
CERT Recently Published Vulnerability Notes
L
LINUX DO - 最新话题
T
Tor Project blog
T
The Exploit Database - CXSecurity.com
MongoDB | Blog
MongoDB | Blog
Webroot Blog
Webroot Blog

ashishb.net

A day in Luxembourg - the richest country in the world I was asked to install malware during a fake interview Book summary: Breakneck - China's quest to engineer the future by Dan Wang Book summary: How to Teach Your Baby to Read Book Summary: The Discontented Little Baby Book by Pamela Douglas Introducing Amazing Sandbox - run third-party tools and AI agents securely on your machine Why software outsourcing gets a bad reputation? Book summary: The Natural Baby Sleep Solution by Polly Moore A day in Antwerp, Belgium Journey of online influencers Two days in Brussels, Belgium Shortcuts - when we love them and when we don't A visit to Rakhigarhi Three days in overhyped Paris Empty Japan, crowded Tokyo The real lock-in in GitHub is not the code, but the stars 11-day Norwegian Breakaway East Caribbean cruise Sanskrit and Sri Lankan Air Force Use REST with Open API The Achilles heel of American capitalism Costa Rica in 4 days At a juice stall in Sri Lanka A short stay at Warsaw, Poland Best practices for using Python & uv inside Docker Two days in Vilnius, Lithuania How IntelliJ IDEs waste disk space Pregnancy Why there aren't many digital nomads from India Two days in Riga, Latvia To keep your machine secure, run third-party tools inside Docker Family Ties in Your DNA: Some relatives are closer than others Doctors per capita Two days in Tallinn, Estonia Ship tools as standalone static binaries Made in America Two days in Helsinki, Finland Maintaining an Android app is a lot of work The land of good deals Two days in Oslo, Norway FastAPI vs Flask performance comparison Google Search is losing to Perplexity Two days in Dublin, Ireland Continuous integration ≠ Continuous delivery World's simplest project success heuristic London in 5 days It is hard to recommend Python in production Inflation, IRS, Credit cards, and Vendors Temu and the Chinese approach Things to do in Miami Florida Revenue vs Cost Axis Language learning as an adult The unanchored babies of the green card limbo Price variance in the United States A day in Louisville, Kentucky A surprisingly positive experience with Air India Unhospitable Airports Android: Don't use stale views USA = Union of Sales and Advertisement A day in Nashville, Tennessee Minimize Javascript in your codebase A day in Birmingham, Alabama In defense of ad-supported products Real vs artificial world The science behind Punjabi singers Hiking Mt. Fuji The Indian startup bubble is insane Repairing database on the fly for millions of users Book Summary: One up on Wall Street by Peter Lynch It is hard to recommend Google Cloud At the Prague airport Kyoto in three days Migrating from WordPress to Hugo Book summary: Sick Societies by Robert B. Edgerton Statistical outcomes require statistical games Illegal immigrants to Europe via Cairo Tokyo in three days Mobs are Status Games Writing Script matters as much as the spoken language Sri Lanka in 5 days LLMs: great for business but bad business Book Summary: Safe Haven by Mark Spitznagel Mac shortcut for typing Avagraha symbol On a bus with an asylum seeker Nicaragua in 5 days When to commit Generated code to version control Why I always buy a local SIM in a foreign country Use Makefile for Android Four days in Guadalajara, Mexico Android Navigation: Up vs Back Hotels vs Airbnb vs Hostels Currency issues in Argentina Abstractions should be deep not wide Some data on podcasting Always support compressed response in an API service A day in El Calafate - Patagonia, Argentina Hermetic docker images with Hugging Face machine learning models American Elections The sound of "ch" API services should always have usage Limits Hiking in El Chaltén - trekking capital of Argentina
Book Summary: A philosophy of software design by John K Ousterhout
Ashish Bhatia · 2022-04-03 · via ashishb.net

The book summarizes the teachings of John from the course CS190 that he teaches at Stanford.

Good system designers get to spend a larger fraction of time in the design phase. Poor designers spend most of their time chasing bugs in complicated and brittle code.

Complexity

  • Problem decomposition is the central design task that programmers face every day. The greatest limitation in writing software is our ability to understand the systems we are creating.
  • Eventually, everyone reaches a point where your first design ideas are no longer good enough; if you want to get great results, you have to consider a second possibility, or perhaps a third, no matter how smart you are.
  • Complexity can be reduced by eliminating special cases or consistently using identifiers. The second approach to complexity is to encapsulate it so that programmers can work on a system without being exposed to all of its complexity at once. Isolating complexity in a place where it will never be seen is almost as good as eliminating the complexity.
  • The waterfall model rarely works well for software. Incremental development means that software design is never done.
  • Tactical programming makes it nearly impossible to produce a good system design. Typically, other engineers must clean up the messes left behind by the tactical tornado, which makes it appear that those engineers (who are the real heroes) are making slower progress than the tactical tornado.
  • Your job as a developer is not just to create code that you can work with easily, but to create code that others can also work with easily. Your primary goal must be to produce a great design, which also happens to work. This is strategic programming.
  • In general, the lower layers of a system tend to be more general-purpose and the upper layers more special-purpose.
  • In general, developers tend to break up methods too much. Splitting up a method introduces additional interfaces, which add to the complexity. It also separates the pieces of the original method, which makes the code harder to read if the pieces are related. You shouldn’t break up a method unless it makes the overall system simpler.

Handling errors and exceptions

  • Exception aggregation works best if an exception propagates several levels up the stack before it is handled; this allows more exceptions from more methods to be handled in the same place. This is the opposite of exception masking: masking usually works best if an exception is handled in a low-level method.
  • When exception handling code fails, it’s difficult to debug the problem, since it occurs so infrequently.
  • The Unix operating system defines file deletion more elegantly. In Unix, if a file is open when it is deleted, Unix does not delete the file immediately.

Documentation

  • Provide precision in comments by clarifying the exact meaning of the code. Other comments provide information at a higher, more abstract, level than the code; these comments provide intuition. The comment that describes a method or variable should be simple yet complete. If you find it difficult to write such a comment, that’s an indicator that there may be a problem with the design of the thing you are describing.
  • If the information in a comment is already obvious from the code next to the comment, then the comment isn’t helpful. One example of this is when the comment uses the same words that make up the name of the thing it is describing.
  • If documentation is duplicated, it is more difficult for developers to find and update all of the relevant copies.

Writing code

  • Once a codebase turns to spaghetti, it is nearly impossible to fix. Google and VMware grew up around the same time as Facebook, but both of these companies embraced a more strategic approach. A developer should not need to understand the implementations of modules other than the one he or she is working on.
  • The greater the distance between a name’s declaration and its uses, the longer the name should be.
  • Adding code can sometimes simplify the interface. For example, adding garbage collection to a system shrinks its overall interface, since it eliminates the interface for freeing objects.
  • Imagine two classes one writing to a file and one reading from it. Even if neither class exposes that information in its interface, they both depend on the file format: if the format changes, both classes will need to be modified. Back-door leakage like this is more pernicious than leakage through an interface because it isn’t obvious.
  • Information hiding can often be improved by making a class slightly larger. Whenever possible, classes should do the right thing without being explicitly asked. Defaults are an example of this.
  • It is more important for a module to have a simple interface than a simple implementation. Configuration parameters are an example of moving complexity upwards instead of down. When deciding whether to combine or separate, the goal is to reduce the complexity of the system as a whole and improve its modularity. For example, in Java, a combined BufferedInputStream + FileInputStream class would have been better. It might provide methods to disable or replace the default buffering mechanism, but most users would not need to learn about them.
  • The module’s functionality should reflect your current needs, but its interface should not. If a system contains adjacent layers with similar abstractions, this is a red flag that suggests a problem with the class decomposition.
  • A pass-through method does nothing except pass its arguments to another method, usually with the same API as the pass-through method. This typically indicates that there is not a clean division of responsibility between the classes. Eliminating pass-through variables can be challenging. One approach is to see if there is already an object shared between the topmost and bottommost methods. Otherwise, all those variables should be combined into a single context variable. Without discipline, a context can turn into a huge grab-bag of data that creates nonobvious dependencies throughout the system. Contexts may also create thread-safety issues; the best way to avoid problems is for variables in a context to be immutable. Unfortunately, I haven’t found a better solution than contexts.
  • Consistency creates cognitive leverage: once you have learned how something is done in one place, you can use that knowledge to immediately understand other places that use the same approach. The best way to enforce coding conventions is to write a tool that checks for violations and makes sure that code cannot be committed to the repository unless it passes the checker.
  • Developing incrementally is generally a good idea, but the increments of development should be abstractions, not features.

Testing

  • Without a test suite, it’s dangerous to make major structural changes to a system. As a result, developers avoid refactoring in systems without good test suites; they try to minimize the number of code changes for each new feature or bug fix, which means that complexity accumulates and design mistakes don’t get corrected.
  • The problem with test-driven development is that it focuses attention on getting specific features working, rather than finding the best design.
  • Before making any changes, measure the system’s existing behavior. This serves two purposes. First, the measurements will identify the places where performance tuning will have the biggest impact. The second purpose of the measurements is to provide a baseline so that you can re-measure performance after making your changes to ensure that performance improved.