One helpful tip per day:)
(The English version follows)
现代计算机的技术，无论是软件还是硬件，都变得无比复杂，想要了解一整个系统几乎变得不太可能。但是深入了解其中的某个部分，或者某个层次还是有可能的。Nelson Elhage 的这篇文章介绍了如何深入了解计算机的某一部分，这些思路对于 debug 非常有启发意义：
最近碰到一些很奇怪的 bug ，也许早点读到这篇文章会让 debug 变得容易很多。
其中一个项目内生成两个配置打 docker 镜像，除了配置文件和数据文件不一样外，其他都一样。结果一个成功，另外一个死活不成功。把所有的配置文件拆开来，又把所有的数据重新下载，甚至在不同的环境下尝试了同样的操作，始终还是同样的结果。最后在原先的 DockerFile 里找到一些端倪，其中一个依赖包不是从 pip 安装的，二是直接从项目的 github 上下载。不管是 pip 还是 github 上的 release branch 都是统一版本，但是 pull 下来的 master branch 已经往前走了好多个版本，两个版本不相互兼容，也没有明确的报错信息，项目的文档上也没有说明。最后使用了 github 上的最新版本才解决问题。
需要更棒的简历，不妨试试我们的 CV Consultation
如果你也想成为更高效的人，欢迎加入我们的 TG group
Modern computer technology, both software and hardware, has become so complex that it is almost impossible to understand an entire system. This article by Nelson Elhage describes how to get deeper into a part of a computer, and these ideas are very inspiring for debugging: 1.
- start by examining simple parts, such as environment/dependencies/versions, etc.
- locate the problem in as small a scope as possible to isolate other possibilities
I recently ran into some very strange bugs, so maybe reading this article earlier would have made debugging a lot easier.
One of the projects uses two configurations to build docker image, and everything is the same except for the configuration file and data file. As a result, one docker image worked and the other didn't. After splitting all the configuration files, re-downloading all the data, and even trying the same operation in a different environment, the result was still the same. Finally, I found some clues in the original DockerFile, one of the dependency packages was not installed from pip, but was downloaded directly from the project's github. The release branch on either pip or github is the same version, but the master branch from pull has already gone several versions ahead, and the two versions are not compatible with each other. There is no clear error message, nor is it explained in the project documentation. Finally, the problem was solved by using the latest version on Github.
If you find today's sharing helpful, why not share it with your friends?
Need a superb CV, please try our CV Consultation
Modern software and hardware systems contain almost unimaginable complexity amongst many distinct layers, each building atop each other.
You will never understand every detail of the implementation of every level on that stack; but you can understand all of them to some level of abstraction, and any specific layer to essentially any depth necessary for any purpose.
Most behaviors in one layer are comprehensible in terms of the concepts of the next layer, and all behaviors can be understood by digging down through enough layers.
If you work with any tool long enough, you will butt up against bugs in the tool which affect you, and it’s valuable at a minimum to be able to accurately describe and diagnose them in terms of the tool’s abstractions, in order to produce an actionable bug report or a minimal reproducer.
The trickiest bugs are often those that span multiple layers, or involve leaky abstraction boundaries between layers.
An attacker attacking a system isn’t bound by the documented or intended behavior of any layer; she cares about how the system actually behaves in practice, potentially including when one layer or input is “out-of-spec.”
I have become very uncomfortable working in software systems where I don’t have a good model of the underlying layers, and this discomfort can sometimes be harmful to accomplishing my goals.
I am uncomfortable until I understand the roles and relationships of all the components I’m interacting with, at least at a high level.
It’s nearly always worth trying the easier approach first (upgrading a dependency, reaching for the debugger, a few passes of trial-and-error cargo-culting from working examples), and only reach for the big guns if those tools fail you.
Learning more about software systems is a compounding skill.
Understanding immensely complex systems may seem out of grasp at first, but the more you try the easier it becomes.