Clean Code 笔记

Code is clean if it can be understood easily – by everyone on the team. Clean code can be read and enhanced by a developer other than its original author. With understandability comes readability, changeability, extensibility and maintainability. 参考: https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29 General rules Follow standard conventions. Keep it simple stupid. Simpler is always better. Reduce complexity as much as possible. Boy scout rule. Leave the campground cleaner than you found it. Always find root cause. Always look for the root cause of a problem. Design rules Keep configurable data at high levels. Prefer polymorphism to if/else or switch/case. Separate multi-threading code. Prevent over-configurability. Use dependency injection. Follow Law of Demeter. A class should know only its direct dependencies. Understandability tips Be consistent. If you do something a certain way, do all similar things in the same way. Use explanatory variables. Encapsulate boundary conditions. Boundary conditions are hard to keep track of. Put the processing for them in one place. Prefer dedicated value objects to primitive type. Avoid logical dependency. Don’t write methods which works correctly depending on something else in the same class. Avoid negative conditionals. Names rules Choose descriptive and unambiguous names. Make meaningful distinction. Use pronounceable names. Use searchable names. Replace magic numbers with named constants. Avoid encodings. Don’t append prefixes or type information. Functions rules Small. Do one thing. Use descriptive names. Prefer fewer arguments. Have no side effects. Don’t use flag arguments. Split method into several independent methods that can be called from the client without the flag. Comments rules Always try to explain yourself in code. Don’t be redundant. Don’t add obvious noise. Don’t use closing brace comments. Don’t comment out code. Just remove. Use as explanation of intent. Use as clarification of code. Use as warning of consequences. Source code structure Separate concepts vertically. Related code should appear vertically dense. Declare variables close to their usage. Dependent functions should be close. Similar functions should be close. Place functions in the downward direction. Keep lines short. Don’t use horizontal alignment. Use white space to associate related things and disassociate weakly related. Don’t break indentation. Objects and data structures Hide internal structure. Prefer data structures. Avoid hybrids structures (half object and half data). Should be small. Do one thing. Small number of instance variables. Base class should know nothing about their derivatives. Better to have many functions than to pass some code into a function to select a behavior. Prefer non-static methods to static methods. Tests One assert per test. Readable. Fast. Independent. Repeatable. Code smells Rigidity. The software is difficult to change. A small change causes a cascade of subsequent changes. Fragility. The software breaks in many places due to a single change. Immobility. You cannot reuse parts of the code in other projects because of involved risks and high effort. Needless Complexity. Needless Repetition. Opacity. The code is hard to understand.

April 9, 2026 · 3 min · Theme PaperMod

CS 学习工作流

本文由 简悦 SimpRead 转码, 原文地址 csdiy.wiki CS 自学指南 Contributed by @HardwayLinka 计算机领域的知识覆盖面很广并且更新速度很快,因此保持终身学习的习惯很重要。但在日常开发和学习的过程中,我们获取知识的来源相对复杂且细碎。有成百上千页的文档手册,也有寥寥数语的博客,甚至闲暇时手机上划过的某则新闻和公众号都有可能包含我们感兴趣的知识。因此,如何利用现有的各类工具,形成一套适合自己的学习工作流,将不同来源的知识碎片整合进属于自己的知识库,方便之后的查阅与复习,就显得尤为重要。经过两年工作之余的学习后,我磨合出了以下学习工作流: 底层核心逻辑 一开始我学习新知识时会参考中文博客,但在代码实践时往往会发现漏洞和 bug。我逐渐意识到我参考的信息可能是错误的,毕竟发博客的门槛低,文章可信度不高,于是我开始查阅一些相关的中文书籍。 中文书籍的确是比较全面且系统地讲解了知识点,但众所周知,计算机技术更迭迅速,又因为老美在 CS 方面一直都是灯塔,所以一般中文书籍里的内容会滞后于当前最新的知识,导致我跟着中文书籍实践会出现软件版本差异的问题。这时我开始意识到一手信息的重要性,有些中文书籍是翻译英文书籍的,一般翻译一本书也要一两年,这会导致信息传递的延迟,还有就是翻译的过程中信息会有损失。如果一本中文书籍不是翻译的呢,那么它大概率也参考了其他书籍,参考的过程会带有对英文原著中语义理解的偏差。 于是我就顺其自然地开始翻阅英文书籍。不得不说,英文书籍内容的质量整体是比中文书籍高的。后来随着学习的层层深入,以知识的时效性和完整性出发,我发现 源代码 > 官方文档 > 英文书籍 > 英文博客 > 中文博客,最后我得出了一张 信息损失图: 虽然一手信息很重要,但后面的 N 手信息并非一无是处,因为这 N 手资料里包含了作者对源知识的转化——例如基于某种逻辑的梳理(流程图、思维导图等)或是一些自己的理解(对源知识的抽象、类比、延伸到其他知识点),这些转化可以帮助我们更快地掌握和巩固知识的核心内容,就如同初高中学习时使用的辅导书。 此外,学习的过程中和别人的交流十分重要,这些 N 手信息同时起了和其他作者交流的作用,让我们能采百家之长。所以这提示我们学习一个知识点时先尽量选择质量更高的,信息损失较少的信息源,同时不妨参考多个信息源,让自己的理解更加全面准确。 现实工作生活中的学习很难像学校里一样围绕某个单一知识点由浅入深,经常会在学习过程中涉及到其他知识点,比如一些新的专有名词,一篇没有读过的经典论文,一段未曾接触过的代码等等。这就要求我们勤于思考,刨根究底地 “递归” 学习,给多个知识点之间建立联系。 选择合适的笔记软件 工作流的骨架围绕 单个知识点多参考源,勤于提问给多个知识点之间建立联系 的底层核心逻辑建立。我们写论文其实就是遵循这个底层逻辑的。论文一般会有脚注去解释一些关键字,并且论文末尾会有多个参考的来源,但是我们平时写笔记会随意得多,因此需要更灵活的方式。 平时写代码习惯在 IDE 里一键跳转,把相关的函数和实现很好地联系在了一起。你也许会想,如果笔记也能像代码那样可以跳转就好了。现在市面上 双链笔记软件 就可以很好地解决这一痛点,例如 Roam Research、Logseq、Notion 和 Obsidian。Roam Research 和 Logseq 都是基于大纲结构的笔记软件,而 大纲结构 是劝退我使用这两款软件的原因。一是 大纲结构 做笔记容易使文章纵向篇幅太长,二是如果嵌套结构过多会占横向的篇幅。Notion 页面打开慢,弃之。最终我选择了 Obsidian,原因如下: Obsidian 基于本地,打开速度快,且可存放很多电子书。我的笔记本是 32g 内存的华硕天选一代,拿来跑 Obsidian 可以快到飞起 Obsidian 基于 Markdown。这也是一个优势,如果笔记软件写的笔记格式是自家的编码格式,那么不方便其他第三方拓展,也不方便将笔记用其他软件打开,比如 qq 音乐下载歌曲有自己的格式,其他播放器播放不了,这挺恶心人的 Obsidian 有丰富的插件生态,并且这个生态既大又活跃,即插件数量多,且热门插件的 star 多,开发者会反馈用户 issue,版本会持续迭代。借助这些插件,可以使 Obsidian 达到 all in one 的效果,即各类知识来源可以统一整合于一处 信息的来源 Obsidian 的插件使其可以支持 pdf 格式,而其本身又支持 Markdown 格式。如果想要 all in one,那么可以基于这两个格式,将其他格式文件转换为 pdf 或者 Markdown。 那么现在就面临着两个问题: ...

April 9, 2026 · 7 min · Theme PaperMod

高效程序员的45个习惯

一、态度决定一切 1. 做事 应该把重点放到解决问题上,而不是在指责犯错者上面纠缠。 把矛头对准问题的解决办法,而不是人,这是真正有用处的正面效应。 2. 欲速则不达 你必须要理解一块代码是如何工作的,但是不一定需要成为一位专家。只要你能使用它进行有效的工作就足够了,不需要把它当作毕生事业。 如果有一位团队成员宣布,有一块代码其他人都很难看懂,这就意味着任何人(包括原作者)都很难维护它。请让它变得简单些。 不要急于修复一段没能真正理解的代码。这种 +1 / -1 的病症始于无形,但是很快会让代码一团糟。要解决真正的问题,不要治标不治本。 多有的大型系统都非常复杂,因此没有一个人能完全明白所有的代码。除了深入了解你正在开发的那部分代码之外,你还需要从更高的层面来了解大部分代码的功能,这样就可以理解系统各个功能模块之间是如何交互的。 如果系统的代码已经恶化,参考第4点(排除万难,奋勇前进) 。 3. 对事不对人 让我们骄傲的应该是解决了问题,而不是比较出谁的注意更好。 尽力贡献自己的好想法,如果你的想法美欧被采纳也无需生气。不要因为只是想体现自己的想法而对拟定的好思路画蛇添足。 脱离实际的反方观点会使争论变味。若对一个想法有成见,你很容易提出一堆不太可能发生或不太实际的情形去批驳它。这时,请先扪心自问:类似问题以前发生过吗?是否经常发生? 只有更好,没有最好。尽管"最佳实践"这个术语到处在用,但实际上不存在”最佳“,只有在某个特定条件下更好的实践。 不带个人情绪并不是要盲目地接受所有的观点。用合适的词和理由去解释为什么不赞同这个观点或方案,并提出明确的问题。 4. 排除万难,奋勇前进 如果你说天快要塌下来了,但其他团队成员都不赞同。反思一下,也许你是正确的,但是你没有解释清楚自己的理由。 如果你说天快要塌下来了,但其他团队成员都不赞同。认真思考一下,他们也许是对的。 如果设计或代码中出现了奇怪的问题,花时间去理解为什么代码会是这样的。如果你找到了解决办法,但代码仍然令人费解,唯一的解决办法是重构代码,让它可读性更强。如果你没有马上理解这段代码,不要轻易地否定或重写它们。那不是勇气,而是鲁莽。 当你勇敢地站出来时,如果收到了缺乏北京只是的抉择者的抵制,你需要用他们能够听懂的话语表达。”更清晰的代码“是无法打动生意人的。解决资金、获得更好的投资回报,避免诉讼以及增加用户利益,会让论点更有说服力。 如果你在压力下要对代码质量作出妥协,你可以指出,作为一名开发者,你没有职权毁坏公司的资产(所有的代码)。 二、学无止境 5. 跟踪变化 你先不要精通所有技术,但需要清楚知道行业的动向,从而规划你的项目和职业规划。 许多新想法从未变得羽翼丰满,成为有用的技术。即使是大型、热门和资金充裕的项目也会有同样的下场。你要正确把握自己投入的精力。 你不可能精通每一项技术,梅雨哦必要去做这样的尝试。只要你在某一些方面成为专家,就能使用同样的方法,很容易地成功成为新领域的专家。 你要明白为什么需要这项新技术– 它试图解决什么样的问题?它可以被用在什么地方? 避免在一时冲动的情况下,只是一位内想学习而将应用切换到新的技术、框架或开发语言。在做决策之前,你必须评估新技术的优势。开发一个小的原型系统,是对付技术狂热者的一剂良药。 6. 对团队投资 尽量让讲座走进团队 坚持有计划有规律地举行讲座。持续、小步前进才是敏捷。稀少、间隔时间长的马拉松式会议非敏捷也。 不要局限于纯技术的图书和主题,相关的非技术主题也会退对有帮助。 7. 懂得丢弃 要果断丢弃旧习惯,一味遵循过时的就习惯会危害你的职业生涯。 不是完全忘记旧的习惯,而是只在使用适当的技术时使用它。 对所有使用的语言,要总结熟悉的语言特性。并且比较这些特性在新语言或新版本中有什么不同。 8. 打破沙锅问到底 你可能会跑题,问了一些于主题无关的问题。就好比是,如果汽车启动不了,你问是不是轮胎出了问题,者是没有任何帮助的。问“为什么”,但是要问到点子上。 当你问“问什么”的时候,也许会被反问: “为什么你问这个问题?”在提问之前,想好你提问的理由,这会有助于你问出恰当的问题。 “这个,我不知道”是一好的起点,应该由此进行更进一步的调查,而不应该嘎然结束。 9. 把握开发节奏 每天结束的时候,测试代码,提交代码,没有残留的代码。 不要搞得经常加班。 以固定、有规律的长度运行迭代。 有规律的开发节奏会暴露很多问题,让你有更多鼓起勇气的借口。 一点点的成功也是一个很大的激励。小而可达到目标会让每个人全速前进。 三、交付用户想要的软件 10. 让客户做决定 记录客户做出的决定,并注明原因。 不要用低级别和没有价值的问题打扰繁忙的业务人员。如果问题对他们业务没有影响,就应该是没有价值的。 不要随意假设低级别的问题不会影响他们的业务。如果能够影响他们的业务,就是有价值的问题。 如果业务负责人回答“我不知道”,这时一个称心如意的答案。也许是他们还没有想那么远,也许是他们只有看到运行的实物才能评估出结果。尽你所能为他们提供建议,实现代码的时候也要考虑可能出现的变化。 11. 让设计指导而不是操纵开发 设计可以分为两层:战略和战术。 前期的设计属于战略,通常只有在没有深入理解需求的时候需要这样的设计。良好的战略设计应该扮演地图的角色,指引你向正确的方向前进。任何设计仅是一个起跑点:它就像你的代码一样,在项目的生命周期中,会不停地进一步发展和提炼。 ...

April 9, 2026 · 2 min · Theme PaperMod