作者 陈怀临 | 2011-10-19 16:15 | 类型 图书推荐, 弯曲推荐, 科技普及 | 79条用户评论 »
工具箱 本文链接 | | 打印此页 | 79条用户评论 »
“弯曲评论荣誉推荐:李先静 。《系统程序员成长计划》”有79个回复
确是作者集多种著作和自身深刻经验体会的大集,适合作为大学或刚毕业学生的精读教材,一定能减少许多弯路,尤其是那些本身并不是很适合做程序员却因为生计而走上这条道路的同学,虽然他们不一定能成为优秀的程序员,但他们仍然需要编出优秀的程序。
这本书真的很不错,当初读完之后感觉特别舒服。
他里面有一句
>> 调试器用的越多,水平越差
我不赞同,这个多和少,是怎么划分的?另外为什么用的越多,水平越差?
李先生可能认为在写程序的时候,代码已经在全局构思好了,所以写下来没什么BUG。
我也赞同这个思路,但是老实说,这句话说的太死了。
调试器不仅仅是调试BUG的,也是了解程序内部的一种手段。
在《Coder at work》里面很多人刚开始写程序的时候,都是在一些软件的常用操作上设断点,然后执行下,一步步看里面是怎么走的。
Bill Joy刚开始学emacs貌似也是如此。
“调试器用的越多,水平越差”是很经典的体验,好的程序是主要设计出来的,做程序的时候要尽量减少可以依赖调试来把程序做优秀的想法,否则很难成为一个优秀的程序员,再进一步,调试也应该是有设计的,而不是调出来的。靠调试了解内部结构的更多目的是为了以后更好通过了解系统来设计程序
其实著名的《人月神话》已经很清楚的讲到了优秀开发人员的问题,我想目前大行其道的敏捷开发的前提就是开发人员要足够优秀吧。
系统程序员的成长可以参考金庸系列著作。
“适合作为大学或刚毕业学生的精读教材”
的确是这样,看过此书~~
作者太谦虚了。个人认为,一般在华为工作5年以内的C程序员,都需要学习一下。5年以上的就不需要了,因为要么已经是领导了,要么已经开始混日子了……
记得诺西面试时,面试官最后的建议是想学好C语言,扔掉调试器。奉劝还在学校的童鞋们,扔掉谭浩强那本书,看看C陷阱与缺陷,C专家编程等
快20年没碰过C了,这书好啊。要那会做毕业设计的时候看到,能省好多时间。
nice design to avoid debug
–Paul Mckenney
作者是我多年前认识的一个朋友,也是一个认真做事的,他本不是计算机专业,和很多远涉重洋的硅工一样,为了生存,走向了码农生涯。再多的不说了。性格上有某种偏执。所以写成了本书,估计写了几年。至少是其工作的总结。很实在,而不是虚玄。不像西晋某些大家,虽然是大家,但就会空谈一些概念符号。
真的很好的书,多谢作者,看起来是很实在的人,费了不少功夫,技术界需要这样的人。
作为培训新职员,尤其是刚毕业的很是管用。 至少比较系统的讲述了系统程序员的方方面面
还没有读完, 但是很赞同作者的这个思想“一流的高手”不是培训来造就的。 环境却不可能让一流的高手们都走到一起, 所以感谢作者写这本书, 让准高手们造就自己, 也让需要的人来培训合格的人才
我觉得写的至少很有诚意,比那个自吹自擂的好多了
“调试器用的越多,水平越差” 这话说得有点过了。写程序,理想的是设计先行。但除非是做过的,很熟悉的,否则是设计和验证同时进行的,调试工具就少不了。还有一个是入手别人的代码,调试器更是方便理解别人的思路。所以对后来的学习者,还是忽略为好。能顺溜地掌握各种调试工具和方法,对开发自己的代码,或者理解别人的思路都是很有帮助的。
即使是了解代码, 也不赞成使用调试器。读代码, 最好先能读懂代码的框架,层次架构。作者的想法。
读为主,调试工具为辅可能对优秀程序员的成长更好一点
1 有相当一部分是没法用调试器的(包括仿真机) 2 用BUG比较多的系统包括OS compiler processor比较有助于成长(这个就是我等老民工的优势,小民工用的都比较成熟了很多东西无法深如了解) 3 talent的优势是后天无法超越的。
“调试器用的越多,水平越差”是业界高水平程序员的一致见解,shuyong你一定没和高手程序员打过交道。
呵呵,我相信我碰到的大多数是普通码工,我也相信大多数码工不会成为所谓的高手。如果这书是为高手而做,估计不会有什么销量。要为熟练的码工服务,才是好的目标。
总之,我认为多熟悉一种工具,就多一种解决方法。没有必要为了某种标志,就硬绷着不用某种工具,有点太搞笑了。
开始多是以熟练掌握调测工具上手,但之后,有心的程序员自然会转到以良好的设计避免冗长的调测为主。一个好的程序员写出来的程序,也需要调测,但和初级程序员的程序比,调试的工作量和难度差别非常大。
理客兄说的太对了。不愧是弯曲的资深弯友。少用调试器对所有程序员都有帮助,包括普通码工。这绝不是一种偏激行为,也不是为了假装高手的一种所谓搞笑行为。原因我说两点。 一 调试器不能发现所有错误。 二 常用调试器会产生依赖心理,有的人写了多年程序却连语法都搞不清,还不是调试器害的。 shuyong我回复你,是往你兜里装钱,不知你想明白没。
我买了本书。但是,书中大部分程序都是用c++写的。其中的万能链表,我不认同。我觉得万能链表,就应该是Linux Kernel中的list_head。
这本书我没有看下去。
好的程序是设计出来 这才是硬道理 80%的错误其实是设计上的错误,或者设计时没有考虑到位 所以很赞成 “调试器用的越多,水平越差”
看不上调试器的其实还不是真的高手。见过那些几个小时上手一门新语言的高手吗?见过那些随时能卷起袖子编码的商业高手吗?他们的法宝就是调试器。
Matt好像在说我。。。?:-)。当然,我是用调试器,但不依赖调试器。我以前是给人写printf的。没事,大家来pk一下。谁知道printf如何写?不吭声的吧。要写printf,要先整uart print。要整uart,要先整LED。估计弟兄们都不坑声了。。。
我年轻的时候最牛的一件事情:一个星期,用一个完全不懂的chipset(GT64360),把4张CPU卡。每个卡上是Dual CPU。通过一个主控卡。然后把8个CPU全部带起来。---童总说的ISG2000
哇,首席就是牛。小弟对您的敬佩有如滔滔江水绵延不绝,有如黄河泛滥,一发不可收拾。先拍个马屁哈,实际上这两年从弯曲上学到不少东西,感谢首席和各位弯友,如果前面的评论言辞过激,我先道个歉。啥时首席来北京,小弟一定带上家乡菜和徐静蕾给首席接风洗尘。
感谢分享,如果有个目录或者书签就更好了
调试器可以用,但不能滥用!
太好了,好好的拜读一下。
随便看了一下,起码对于multithread下Volatile用法描述肯定不准确。奇怪还是有那么多人被误导volatile在multithread的作用
回楼上的。
其实你还是没有理解我的意思。
我的意思是要多掌握各种工具,碰到问题觉得哪种熟悉就先用哪个。调试器是常用工具之一,是开发经常要使用的。如果调试器发现不了问题,那就换另一种方法。如果开发多年,对例如语法这些技术细节还不清楚,其实怪不到调试器上,是码工自己对自己要求不高,不思进取而已。如果懒惰不学习,用什么工具和方法都会有相同的结局。
软件开发,设计先行。调试和测试手段,只能发现问题,但不能解决问题,更不能预防问题。这些都是熟练的开发人员该有的共识。但只要是软件,都会有BUG,可能除了TeX系统之外。而且系统是不断进化和发展的,所以BUG会不断出现。所以熟悉各种调试手段是很重要的,调试器是最先熟悉和最常用的工具。
我所理解的高手,对系统会有深刻的把握,对细节有深刻的理解,对调试手段有精熟而灵活地应用。一个印象深刻的例子是SUN工程师写的书里的例子。故事说SUN的OS里面有一个顽固的BUG,大家怎么也找不着。崩溃的线索很少,有可能是和某个结构的偏移17的数据访问有关,但是哪个结构未知。后来有人根据这些提出了一个方案,反汇编OS IMAGE,然后用grep搜索17这个数字。正常而言,17这数应该不会用太多。结果经过几个小时反汇编得到多少MB的文件,然后再经过几个小时的搜索,终于得到了十几个含17数字的代码行。经过追查,很快就查到了有个数据结构访问有one-off的错误。这个例子说明,高手写的系统,一样会有表面很诡异,实则很普通的BUG。而高手,则是在别的方法都无效后,还能想出方法解决问题。
还有一个例子,就是常有的传说,高手用示波器调代码。一个软件高手,要在关键时刻,会用敢用示波器调试代码。但这也是在各种常规手段无效之后的方法。如果每个BUG都用示波器去调试,不被人笑死,自己也要累死。
前面之所以说”调试器用的越多,水平越差”这句有些过了,是想给后来者一个提醒。调试器一定是最先熟悉和最常用的工具。随着经验的积累和水平的提高,各种调试手段也会掌握得越来越多。因此各种方法的使用率就会逐步降低。这是一种自然发展的事情。但因此就推论出”调试器用的越少,水平越高”,实在是一种只看现象不想本质的认识了。再进一步反过来推论”调试器用的越多,水平越差”,是有点搞笑了。虽然使用率低,但高手用调试器的时间不会比别人少。我记得好像微软的那本”代码大全”里面还要求重要的代码要用调试器走一遍了。也不知道他们内部是不是是这样执行的了。有知道的人说一声。
因此,不讨论设计阶段,只说调试,随着对系统的把握,对细节的了解,碰到一个BUG,就会有一些直觉和快速的定位方法。如果不对,就该用常规方法了,调试器就是首选之一。如果几种常规方法都不见效,那一个念头就会冒上来:麻烦大了。后面各种奇门兵器轮番上阵,那才是苦不堪言的时候了。
呵呵,上面的应该是回31楼的。
调试器用的越多,水平越差。这句话没什么逻辑
就想老司机永远觉得开手动档要比自动档要技术含量一样。殊不知现在的技术在大部分路况下自动档要比手动档省油的
打不开啊
shuyong首席都出来打圆场,你还发长篇大论干嘛,多关心技术问题,弯曲不是吵架的地
To首席,前半句是说你,后半句是说我 To柳橙汁,叫徐家妹子洗尘之类的事可以列席吗?
shuyong对”调试器用的越多,水平越差”的理解,个人感觉应该是比较深入正确的。每个码工成长过程中肯定会经历痛苦的调试阶段,示波器、LED点灯、调试器、反汇编指令分析、系统debug信息分析这些是不同层面的调试手段,项目中会有使用顺序优先级,不能说高手一上来不管三七二十一就直接拿起示波器分析去了,那绝对是蠢蛋一个。高手和初学者的差别在于,初学者可能只会用debug信息分析不出问题来就卡住了,而高手面对问题会有一定的直觉,在定位问题过程中敢用并且会用各种手段快而准地定位出问题来。不全面地掌握各种调试手段,初学者何以成长为高手?调试器是不可缺少的一件利器,只是在成为高手之后确实会用得越来越少。
看了下,如楼上某同志说的一样,对volatile的解释还真的是错误的,也许作者可能确实不是计算机科班出身,对体系结构不了解吧 另外list_head的确是个很好的万能链表,作者其实只是想告诉读者链表设计的思路而已。
我来看看。我对volatile的理解应该没有问题,可以映射到sync,和eieio等指令上。。。
陈首席的C语言不过关。 volatile仅仅是编译器优化相关,就是告诉编译器不要做任何优化。
举例说明: nor flash write一般都需要一个命令序列: 例如: * 0xaa = 0×11; * 0xaa = 0×22; * 0xaa = 0×33;
如果不加volatile,会认为前面两句赋值没有意义,直接就strip掉了。
====
而mips 的sync, powerpc的eieio,这些指令是用来做memory barrier的。只有在代码中,手工加入上述汇编指令,才能体现出来。编译器是不会自动生成sync等的。
对于单处理机系统,sync等没有意义。 sync等只在多核系统中有意义。
ls的胆子好大,哈哈
反了:-)。在单机系统中,但在嵌入式系统中,例如有DMA,FPGA的情况下,要各位注意。。。
另外,要注意的是:volatile会force编译器一定做Memory的Load,确保是从内存中拿的。
这也是为什么小李的代码中做锁的道理。
江湖上要时刻小心小弟要造反,特别是厉害的。这个小弟不错。sync,eieio还都什么都知道。。。
我问一个狠的:
在许多ASIC和Chipset中,都会提供许多硬件做的mutex register,从而你不需要做通过volatile的mem based spinlock。
Question: 用哪个快?用哪个好?优缺点是什么。。。
回首席问题,不对请指教。
”在许多ASIC和Chipset中,都会提供许多硬件做的mutex register,从而你不需要做通过volatile的mem based spinlock。“
在单CPU系统中,显然register快,但是多CPU系统中,用mutex register显然无法保证多个CPU同时读volatile变量的一致性。这个时候就还是用mem based。X 86下直接读mem进MMX register保证atomic,速度也不慢,大概相当于L1 cache的速度。
所以register要更快一点但是要小心,普通情况下还是用mem solution好,速度也不错。
重新回答下上面问题,可能刚才理解不是很准确。如果是在critical section之外,volatile还是保证编译器不会cache变量到register里面.但是inside critical section,只有一个thread能拿到,这时变量就不再是volatile,相当于做了一个const cast,这样变量在register里面就没有问题了直到退出critical section。
这个问题确实头大,对体系结构不熟悉想我就还是乖乖调用pthread。
往首席指教
一个问题就问出底了。。。单CPU下你要hardware mutex做毛用啊。。。
首席又想起64360了吧。。。
那大师们也来分析下,我们也好有长进
这个要看是硬件读写这个地址频繁,还是软件读写这个地址频繁吧
或者说,remote多,还是local多?
呵呵,没想到这么热闹,住了一周院,回来后又被老婆没收电脑,所以才看到。关于调试器的问题,在书中确实有些极端,主要是我看见太多人花太多时间去调试烂程序了。实际上我的调试能力比编程能力更强,我大部分时间是解决项目中的疑难问题。我讨厌调试却擅长调试,今年打算写本如何解决疑难问题的书,写了30多页,因为生病搁下了。呵,我还不知道能不能闯过去,如果有机会再写,我会把这些年的调试心得在弯曲上和大家分享。
“调试器用的越多,水平越差”这句话我比较赞同,如果你发现自己每次写代码都和以前一样需要大量的调试,那肯定是没有多大进步的,有进步的情况应该是调试器用得越来越少才对~
To lixianjing:
请问是什么病? 听你的话比较严重,大伙很担心。
谢谢大家关心。今年一直在死亡的边缘徘徊,不过治疗还算顺利,治疗还需要一个较长的过程,虽然不太相信奇迹,我还是相信能挺过去的。
lixianjing童鞋,写书不是那么重要滴。你要保重身体,祝你早日恢复健康。
lixianjing童鞋 保重身体!!!
粗略看了一下,里面涉及的内容很实用,值得继看,打算推荐给组内其他同事一起学习一下。
我粗略读了一下,很喜欢这本书。。。李老师身体要紧。。保重身体啊。。
身体是革命的本钱,李先静保重!
@lixianjing 祝你早日康复
获益良多,李老师是认真思考的人,祝身体安康。
感觉这本书为我们这些小系统程序员指明了方向和方法。 真心期望李老师身体健康,好人平安!
写得相当好,但是提几个意见: 1.作者开头的编程风格建议条件、循环等仅一行语句也要用{}括住,但是后面快速排序程序的示例中while循环没有用{}括住,呵呵. 2.C语言很难做出C++ STL里面的迭代器,因为模板的代码是不需要函数指针做通用性抽象处理的,因此C++ STL号称可以和手工写出的代码效率相当但不损失抽象性。模板很像代码生成器宏,但是比宏功能强大的多,感兴趣的可以试试C语言里用宏怎么做,估计代码可读性大打折扣,所以我不喜欢在C语言里面搞什么迭代器。 3.既然文档的目标是如何写出商用代码,那么快速排序的程序还是有缺陷的。其中之一是递归时没考虑优先递归长度较小的子区间,否则堆栈搞不好溢出了。如果递归时优先递归长度较小的子区间,那么堆栈深度最大LogN,应用程序基本上不会有问题。感兴趣的可以参考各种商用库的快速排序函数或者优秀的教材。
follow your heart,也要comply with your body。Jobs的性格是不会很承认自己后悔晚做手术,但大家都希望英才能有更长的时间给大家留下更多的精彩,祝先静兄早日康复,并能hold住健康的身体。
@lixianjing 愿李老师早日康复。皮囊虽没有精神重要,但至少需要它充当承载介质。自己有过一段时间因为生病耽误了些事情,后来才意识到健康的重要。也希望所有忙于工作的前辈们保重!
祝xianjing兄身体康复。
一直都在关注李先静老师的博客和网站,学习到不少东西。虽然不太可能做码农了,但还是买了李老师的书。今天刚送到,每想到却在弯弯看到李老师生病的消息…… 默默地祝你早日康复,继续回来探索精彩的计算机世界。
调试器用的多不多和技术有没有关系这个我不知道, 但自己早已练就了不用调试器调试大部分程序的方法, 哈哈哈哈哈哈
看了中心思想:控制软件复杂度和隔离变化。 这两点Code Complete也提到了,最好结合着一块看
如果书中可以结合一些编程之道的感悟,系统程序员有时是需要一定的感悟和道。工具其次,做事的原则和方法,如何取得平衡,也非常重要。 比如在调试中会碰到各种表象,哪一个该深入下去,哪一个可以略过去。 有时候调试到繁琐的细节的时候,不如退出一步,纵观全局,可能反而恍然大悟。 我记得曾听首席讲座,曾提过几个要点: 仔细阅读硬件文档; 有怀疑的地方往往就是可能以后出问题的地方。 等等。
还有调试,其实态度有时比你的知识和功力更重要。首席曾经提到过“莫生气”,我也在工作中有感悟。保持一颗谨慎,平静的心态很重要。
另外笔者说这些东西为什么强调对系统程序员很重要。我觉得相比于应用程序员,系统程序员面临的对手是这样地: 1、复杂性。系统软件往往运行在不同的软硬件平台,系统软件往往上面和OS,编译器,中间件,硬件平台,体系结构都有关联。这是和其他应用软件所不同的地方。 2、可测性。系统软件的运行环境复杂,不可能做到完全测试。所以出现问题是必然的。 3、没有好的调试工具。
还有培养人的角度,还是要看一个人的性格适不适合当系统程序员。好的系统程序员应该是认真,专注,对自己要求很高。
怪不得最近没看到李老师更新blog,李老师一定要注意身体啊,这本书我看了好几遍了,对于我这样的小菜鸟来说,无疑是顶级的营养品啊。
呵呵,看到上面的各位的评论,深感路途遥远啊。
这本我一看,就深表同意,和unix编程艺术的核心思想相符合,但是也加了很多李老师自己的经验了。
李兄保重身体,闯过这道坎
弯友也要保重自己的身体,享受生活每一天
文笔很好,逻辑清晰,比喻和引用都很贴切。很佩服作者,工作8年水平这么高,很想了就作者的专业化经历,希望做能能分享更多。
前面45-54楼讲了些volatile和hardware mutex的用法,大家的理解很有新意,独特,希望大家继续说一说。
个人理解是volatile是用在一个处理器中,访问硬件寄存器用,不是用于mutex的处理(和mutex无关),外部mutex寄存器用于标示设备目前是否可以访问,是个标示寄存器,在访问共享硬件资源前处理器需确认资源目前是否可访问。
确是作者集多种著作和自身深刻经验体会的大集,适合作为大学或刚毕业学生的精读教材,一定能减少许多弯路,尤其是那些本身并不是很适合做程序员却因为生计而走上这条道路的同学,虽然他们不一定能成为优秀的程序员,但他们仍然需要编出优秀的程序。
这本书真的很不错,当初读完之后感觉特别舒服。
他里面有一句
>> 调试器用的越多,水平越差
我不赞同,这个多和少,是怎么划分的?另外为什么用的越多,水平越差?
李先生可能认为在写程序的时候,代码已经在全局构思好了,所以写下来没什么BUG。
我也赞同这个思路,但是老实说,这句话说的太死了。
调试器不仅仅是调试BUG的,也是了解程序内部的一种手段。
在《Coder at work》里面很多人刚开始写程序的时候,都是在一些软件的常用操作上设断点,然后执行下,一步步看里面是怎么走的。
Bill Joy刚开始学emacs貌似也是如此。
“调试器用的越多,水平越差”是很经典的体验,好的程序是主要设计出来的,做程序的时候要尽量减少可以依赖调试来把程序做优秀的想法,否则很难成为一个优秀的程序员,再进一步,调试也应该是有设计的,而不是调出来的。靠调试了解内部结构的更多目的是为了以后更好通过了解系统来设计程序
其实著名的《人月神话》已经很清楚的讲到了优秀开发人员的问题,我想目前大行其道的敏捷开发的前提就是开发人员要足够优秀吧。
系统程序员的成长可以参考金庸系列著作。
“适合作为大学或刚毕业学生的精读教材”
的确是这样,看过此书~~
作者太谦虚了。个人认为,一般在华为工作5年以内的C程序员,都需要学习一下。5年以上的就不需要了,因为要么已经是领导了,要么已经开始混日子了……
记得诺西面试时,面试官最后的建议是想学好C语言,扔掉调试器。奉劝还在学校的童鞋们,扔掉谭浩强那本书,看看C陷阱与缺陷,C专家编程等
快20年没碰过C了,这书好啊。要那会做毕业设计的时候看到,能省好多时间。
nice design to avoid debug
–Paul Mckenney
作者是我多年前认识的一个朋友,也是一个认真做事的,他本不是计算机专业,和很多远涉重洋的硅工一样,为了生存,走向了码农生涯。再多的不说了。性格上有某种偏执。所以写成了本书,估计写了几年。至少是其工作的总结。很实在,而不是虚玄。不像西晋某些大家,虽然是大家,但就会空谈一些概念符号。
真的很好的书,多谢作者,看起来是很实在的人,费了不少功夫,技术界需要这样的人。
作为培训新职员,尤其是刚毕业的很是管用。
至少比较系统的讲述了系统程序员的方方面面
还没有读完, 但是很赞同作者的这个思想“一流的高手”不是培训来造就的。
环境却不可能让一流的高手们都走到一起, 所以感谢作者写这本书, 让准高手们造就自己, 也让需要的人来培训合格的人才
我觉得写的至少很有诚意,比那个自吹自擂的好多了
“调试器用的越多,水平越差”
这话说得有点过了。写程序,理想的是设计先行。但除非是做过的,很熟悉的,否则是设计和验证同时进行的,调试工具就少不了。还有一个是入手别人的代码,调试器更是方便理解别人的思路。所以对后来的学习者,还是忽略为好。能顺溜地掌握各种调试工具和方法,对开发自己的代码,或者理解别人的思路都是很有帮助的。
即使是了解代码, 也不赞成使用调试器。读代码, 最好先能读懂代码的框架,层次架构。作者的想法。
读为主,调试工具为辅可能对优秀程序员的成长更好一点
1 有相当一部分是没法用调试器的(包括仿真机)
2 用BUG比较多的系统包括OS compiler processor比较有助于成长(这个就是我等老民工的优势,小民工用的都比较成熟了很多东西无法深如了解)
3 talent的优势是后天无法超越的。
“调试器用的越多,水平越差”是业界高水平程序员的一致见解,shuyong你一定没和高手程序员打过交道。
呵呵,我相信我碰到的大多数是普通码工,我也相信大多数码工不会成为所谓的高手。如果这书是为高手而做,估计不会有什么销量。要为熟练的码工服务,才是好的目标。
总之,我认为多熟悉一种工具,就多一种解决方法。没有必要为了某种标志,就硬绷着不用某种工具,有点太搞笑了。
开始多是以熟练掌握调测工具上手,但之后,有心的程序员自然会转到以良好的设计避免冗长的调测为主。一个好的程序员写出来的程序,也需要调测,但和初级程序员的程序比,调试的工作量和难度差别非常大。
理客兄说的太对了。不愧是弯曲的资深弯友。少用调试器对所有程序员都有帮助,包括普通码工。这绝不是一种偏激行为,也不是为了假装高手的一种所谓搞笑行为。原因我说两点。
一 调试器不能发现所有错误。
二 常用调试器会产生依赖心理,有的人写了多年程序却连语法都搞不清,还不是调试器害的。
shuyong我回复你,是往你兜里装钱,不知你想明白没。
我买了本书。但是,书中大部分程序都是用c++写的。其中的万能链表,我不认同。我觉得万能链表,就应该是Linux Kernel中的list_head。
这本书我没有看下去。
好的程序是设计出来 这才是硬道理
80%的错误其实是设计上的错误,或者设计时没有考虑到位
所以很赞成
“调试器用的越多,水平越差”
看不上调试器的其实还不是真的高手。见过那些几个小时上手一门新语言的高手吗?见过那些随时能卷起袖子编码的商业高手吗?他们的法宝就是调试器。
Matt好像在说我。。。?:-)。当然,我是用调试器,但不依赖调试器。我以前是给人写printf的。没事,大家来pk一下。谁知道printf如何写?不吭声的吧。要写printf,要先整uart print。要整uart,要先整LED。估计弟兄们都不坑声了。。。
我年轻的时候最牛的一件事情:一个星期,用一个完全不懂的chipset(GT64360),把4张CPU卡。每个卡上是Dual CPU。通过一个主控卡。然后把8个CPU全部带起来。---童总说的ISG2000
哇,首席就是牛。小弟对您的敬佩有如滔滔江水绵延不绝,有如黄河泛滥,一发不可收拾。先拍个马屁哈,实际上这两年从弯曲上学到不少东西,感谢首席和各位弯友,如果前面的评论言辞过激,我先道个歉。啥时首席来北京,小弟一定带上家乡菜和徐静蕾给首席接风洗尘。
感谢分享,如果有个目录或者书签就更好了
调试器可以用,但不能滥用!
太好了,好好的拜读一下。
随便看了一下,起码对于multithread下Volatile用法描述肯定不准确。奇怪还是有那么多人被误导volatile在multithread的作用
回楼上的。
其实你还是没有理解我的意思。
我的意思是要多掌握各种工具,碰到问题觉得哪种熟悉就先用哪个。调试器是常用工具之一,是开发经常要使用的。如果调试器发现不了问题,那就换另一种方法。如果开发多年,对例如语法这些技术细节还不清楚,其实怪不到调试器上,是码工自己对自己要求不高,不思进取而已。如果懒惰不学习,用什么工具和方法都会有相同的结局。
软件开发,设计先行。调试和测试手段,只能发现问题,但不能解决问题,更不能预防问题。这些都是熟练的开发人员该有的共识。但只要是软件,都会有BUG,可能除了TeX系统之外。而且系统是不断进化和发展的,所以BUG会不断出现。所以熟悉各种调试手段是很重要的,调试器是最先熟悉和最常用的工具。
我所理解的高手,对系统会有深刻的把握,对细节有深刻的理解,对调试手段有精熟而灵活地应用。一个印象深刻的例子是SUN工程师写的书里的例子。故事说SUN的OS里面有一个顽固的BUG,大家怎么也找不着。崩溃的线索很少,有可能是和某个结构的偏移17的数据访问有关,但是哪个结构未知。后来有人根据这些提出了一个方案,反汇编OS IMAGE,然后用grep搜索17这个数字。正常而言,17这数应该不会用太多。结果经过几个小时反汇编得到多少MB的文件,然后再经过几个小时的搜索,终于得到了十几个含17数字的代码行。经过追查,很快就查到了有个数据结构访问有one-off的错误。这个例子说明,高手写的系统,一样会有表面很诡异,实则很普通的BUG。而高手,则是在别的方法都无效后,还能想出方法解决问题。
还有一个例子,就是常有的传说,高手用示波器调代码。一个软件高手,要在关键时刻,会用敢用示波器调试代码。但这也是在各种常规手段无效之后的方法。如果每个BUG都用示波器去调试,不被人笑死,自己也要累死。
前面之所以说”调试器用的越多,水平越差”这句有些过了,是想给后来者一个提醒。调试器一定是最先熟悉和最常用的工具。随着经验的积累和水平的提高,各种调试手段也会掌握得越来越多。因此各种方法的使用率就会逐步降低。这是一种自然发展的事情。但因此就推论出”调试器用的越少,水平越高”,实在是一种只看现象不想本质的认识了。再进一步反过来推论”调试器用的越多,水平越差”,是有点搞笑了。虽然使用率低,但高手用调试器的时间不会比别人少。我记得好像微软的那本”代码大全”里面还要求重要的代码要用调试器走一遍了。也不知道他们内部是不是是这样执行的了。有知道的人说一声。
因此,不讨论设计阶段,只说调试,随着对系统的把握,对细节的了解,碰到一个BUG,就会有一些直觉和快速的定位方法。如果不对,就该用常规方法了,调试器就是首选之一。如果几种常规方法都不见效,那一个念头就会冒上来:麻烦大了。后面各种奇门兵器轮番上阵,那才是苦不堪言的时候了。
呵呵,上面的应该是回31楼的。
调试器用的越多,水平越差。这句话没什么逻辑
就想老司机永远觉得开手动档要比自动档要技术含量一样。殊不知现在的技术在大部分路况下自动档要比手动档省油的
打不开啊
shuyong首席都出来打圆场,你还发长篇大论干嘛,多关心技术问题,弯曲不是吵架的地
To首席,前半句是说你,后半句是说我
To柳橙汁,叫徐家妹子洗尘之类的事可以列席吗?
shuyong对”调试器用的越多,水平越差”的理解,个人感觉应该是比较深入正确的。每个码工成长过程中肯定会经历痛苦的调试阶段,示波器、LED点灯、调试器、反汇编指令分析、系统debug信息分析这些是不同层面的调试手段,项目中会有使用顺序优先级,不能说高手一上来不管三七二十一就直接拿起示波器分析去了,那绝对是蠢蛋一个。高手和初学者的差别在于,初学者可能只会用debug信息分析不出问题来就卡住了,而高手面对问题会有一定的直觉,在定位问题过程中敢用并且会用各种手段快而准地定位出问题来。不全面地掌握各种调试手段,初学者何以成长为高手?调试器是不可缺少的一件利器,只是在成为高手之后确实会用得越来越少。
看了下,如楼上某同志说的一样,对volatile的解释还真的是错误的,也许作者可能确实不是计算机科班出身,对体系结构不了解吧
另外list_head的确是个很好的万能链表,作者其实只是想告诉读者链表设计的思路而已。
我来看看。我对volatile的理解应该没有问题,可以映射到sync,和eieio等指令上。。。
陈首席的C语言不过关。
volatile仅仅是编译器优化相关,就是告诉编译器不要做任何优化。
举例说明:
nor flash write一般都需要一个命令序列:
例如:
* 0xaa = 0×11;
* 0xaa = 0×22;
* 0xaa = 0×33;
如果不加volatile,会认为前面两句赋值没有意义,直接就strip掉了。
====
而mips 的sync, powerpc的eieio,这些指令是用来做memory barrier的。只有在代码中,手工加入上述汇编指令,才能体现出来。编译器是不会自动生成sync等的。
对于单处理机系统,sync等没有意义。
sync等只在多核系统中有意义。
ls的胆子好大,哈哈
反了:-)。在单机系统中,但在嵌入式系统中,例如有DMA,FPGA的情况下,要各位注意。。。
另外,要注意的是:volatile会force编译器一定做Memory的Load,确保是从内存中拿的。
这也是为什么小李的代码中做锁的道理。
江湖上要时刻小心小弟要造反,特别是厉害的。这个小弟不错。sync,eieio还都什么都知道。。。
我问一个狠的:
在许多ASIC和Chipset中,都会提供许多硬件做的mutex register,从而你不需要做通过volatile的mem based spinlock。
Question: 用哪个快?用哪个好?优缺点是什么。。。
回首席问题,不对请指教。
”在许多ASIC和Chipset中,都会提供许多硬件做的mutex register,从而你不需要做通过volatile的mem based spinlock。“
在单CPU系统中,显然register快,但是多CPU系统中,用mutex register显然无法保证多个CPU同时读volatile变量的一致性。这个时候就还是用mem based。X 86下直接读mem进MMX register保证atomic,速度也不慢,大概相当于L1 cache的速度。
所以register要更快一点但是要小心,普通情况下还是用mem solution好,速度也不错。
重新回答下上面问题,可能刚才理解不是很准确。如果是在critical section之外,volatile还是保证编译器不会cache变量到register里面.但是inside critical section,只有一个thread能拿到,这时变量就不再是volatile,相当于做了一个const cast,这样变量在register里面就没有问题了直到退出critical section。
这个问题确实头大,对体系结构不熟悉想我就还是乖乖调用pthread。
往首席指教
一个问题就问出底了。。。单CPU下你要hardware mutex做毛用啊。。。
首席又想起64360了吧。。。
那大师们也来分析下,我们也好有长进
这个要看是硬件读写这个地址频繁,还是软件读写这个地址频繁吧
或者说,remote多,还是local多?
呵呵,没想到这么热闹,住了一周院,回来后又被老婆没收电脑,所以才看到。关于调试器的问题,在书中确实有些极端,主要是我看见太多人花太多时间去调试烂程序了。实际上我的调试能力比编程能力更强,我大部分时间是解决项目中的疑难问题。我讨厌调试却擅长调试,今年打算写本如何解决疑难问题的书,写了30多页,因为生病搁下了。呵,我还不知道能不能闯过去,如果有机会再写,我会把这些年的调试心得在弯曲上和大家分享。
“调试器用的越多,水平越差”这句话我比较赞同,如果你发现自己每次写代码都和以前一样需要大量的调试,那肯定是没有多大进步的,有进步的情况应该是调试器用得越来越少才对~
To lixianjing:
请问是什么病? 听你的话比较严重,大伙很担心。
谢谢大家关心。今年一直在死亡的边缘徘徊,不过治疗还算顺利,治疗还需要一个较长的过程,虽然不太相信奇迹,我还是相信能挺过去的。
lixianjing童鞋,写书不是那么重要滴。你要保重身体,祝你早日恢复健康。
lixianjing童鞋 保重身体!!!
粗略看了一下,里面涉及的内容很实用,值得继看,打算推荐给组内其他同事一起学习一下。
我粗略读了一下,很喜欢这本书。。。李老师身体要紧。。保重身体啊。。
身体是革命的本钱,李先静保重!
@lixianjing
祝你早日康复
获益良多,李老师是认真思考的人,祝身体安康。
感觉这本书为我们这些小系统程序员指明了方向和方法。
真心期望李老师身体健康,好人平安!
写得相当好,但是提几个意见:
1.作者开头的编程风格建议条件、循环等仅一行语句也要用{}括住,但是后面快速排序程序的示例中while循环没有用{}括住,呵呵.
2.C语言很难做出C++ STL里面的迭代器,因为模板的代码是不需要函数指针做通用性抽象处理的,因此C++ STL号称可以和手工写出的代码效率相当但不损失抽象性。模板很像代码生成器宏,但是比宏功能强大的多,感兴趣的可以试试C语言里用宏怎么做,估计代码可读性大打折扣,所以我不喜欢在C语言里面搞什么迭代器。
3.既然文档的目标是如何写出商用代码,那么快速排序的程序还是有缺陷的。其中之一是递归时没考虑优先递归长度较小的子区间,否则堆栈搞不好溢出了。如果递归时优先递归长度较小的子区间,那么堆栈深度最大LogN,应用程序基本上不会有问题。感兴趣的可以参考各种商用库的快速排序函数或者优秀的教材。
follow your heart,也要comply with your body。Jobs的性格是不会很承认自己后悔晚做手术,但大家都希望英才能有更长的时间给大家留下更多的精彩,祝先静兄早日康复,并能hold住健康的身体。
@lixianjing
愿李老师早日康复。皮囊虽没有精神重要,但至少需要它充当承载介质。自己有过一段时间因为生病耽误了些事情,后来才意识到健康的重要。也希望所有忙于工作的前辈们保重!
祝xianjing兄身体康复。
一直都在关注李先静老师的博客和网站,学习到不少东西。虽然不太可能做码农了,但还是买了李老师的书。今天刚送到,每想到却在弯弯看到李老师生病的消息…… 默默地祝你早日康复,继续回来探索精彩的计算机世界。
调试器用的多不多和技术有没有关系这个我不知道,
但自己早已练就了不用调试器调试大部分程序的方法,
哈哈哈哈哈哈
看了中心思想:控制软件复杂度和隔离变化。
这两点Code Complete也提到了,最好结合着一块看
如果书中可以结合一些编程之道的感悟,系统程序员有时是需要一定的感悟和道。工具其次,做事的原则和方法,如何取得平衡,也非常重要。
比如在调试中会碰到各种表象,哪一个该深入下去,哪一个可以略过去。
有时候调试到繁琐的细节的时候,不如退出一步,纵观全局,可能反而恍然大悟。
我记得曾听首席讲座,曾提过几个要点:
仔细阅读硬件文档;
有怀疑的地方往往就是可能以后出问题的地方。
等等。
还有调试,其实态度有时比你的知识和功力更重要。首席曾经提到过“莫生气”,我也在工作中有感悟。保持一颗谨慎,平静的心态很重要。
另外笔者说这些东西为什么强调对系统程序员很重要。我觉得相比于应用程序员,系统程序员面临的对手是这样地:
1、复杂性。系统软件往往运行在不同的软硬件平台,系统软件往往上面和OS,编译器,中间件,硬件平台,体系结构都有关联。这是和其他应用软件所不同的地方。
2、可测性。系统软件的运行环境复杂,不可能做到完全测试。所以出现问题是必然的。
3、没有好的调试工具。
还有培养人的角度,还是要看一个人的性格适不适合当系统程序员。好的系统程序员应该是认真,专注,对自己要求很高。
怪不得最近没看到李老师更新blog,李老师一定要注意身体啊,这本书我看了好几遍了,对于我这样的小菜鸟来说,无疑是顶级的营养品啊。
呵呵,看到上面的各位的评论,深感路途遥远啊。
这本我一看,就深表同意,和unix编程艺术的核心思想相符合,但是也加了很多李老师自己的经验了。
李兄保重身体,闯过这道坎
弯友也要保重自己的身体,享受生活每一天
文笔很好,逻辑清晰,比喻和引用都很贴切。很佩服作者,工作8年水平这么高,很想了就作者的专业化经历,希望做能能分享更多。
前面45-54楼讲了些volatile和hardware mutex的用法,大家的理解很有新意,独特,希望大家继续说一说。
个人理解是volatile是用在一个处理器中,访问硬件寄存器用,不是用于mutex的处理(和mutex无关),外部mutex寄存器用于标示设备目前是否可以访问,是个标示寄存器,在访问共享硬件资源前处理器需确认资源目前是否可访问。