程序员的生活就是解决一个又一个问题,永无止境。
根本的指导方针
1.首先写代码的时候最好不要有缺陷。最好的修复方法就是让bug胎死腹中。
良好的单元测试
强制数据库约束
使用输入验证框架
避免未实现的“else”条件
在应用到主程序之前知道如何在孤立的情况下使用
日志
2.print语句。往往额外输出个一两行将有助于隔离问题。
3.切换至详细的日志记录。详细的日志记录有助于发现更多的线索。
4.搜索日志。如果日志太多,可采取关键字或错误代码来搜索日志文件。
5.开启自动换行和关闭自动换行。控制日志的自动换行也非常有用。
6.搜索不同的日志。主服务器的日志可能并不是唯一有用的日志。
7.Windows事件日志。日志文件的另一个来源可能是操作系统本身。
8.制作有用的日志记录。有时,如果你没有得到任何有用的日志记录,那么你可能需要自己写。
与其他人交流
9.询问一些可能知道问题答案的人。
10.问”愚蠢“的问题。可能你觉得这些问题很愚蠢,但其实并不是。
11.将问题解释给队友。他们可能知道答案或者能提出一些你并没有想到过的事情。
12.将问题解释给你的狗。述说的对象是谁其实没有关系,但是能让你从不同角度分析问题。
写作
13.描述问题。用最准确和最精确的语句描述问题,有助于你去思考可能的解决方案。
14.问题日记。创建一个文本文件来记录已经尝试的各种方法,包括代码片段、配置设置以及产生的任何错误。
15.记录问题和解决方案。有没有这样的情况,突然看到一个似曾相识的问题,只记得解决过但却忘记了是如何解决的?可以将问题和解决方案记录到一个容易搜索的地方,如维基、缺陷跟踪,甚至可以发送电子邮件给自己。
支持
16.阅读FAQ。
17.提交支持请求。如果有可用的产品/库的支持,那么就用。
18.在你点击send之前,请三思。写支持请求能让你再一次思考问题,有时候就在你点击send按钮之时,突然灵机一动就想到了解决问题的方法或者是新的线索。
19.其他方面的支持。可以与开发人员直接面对面交流,最好是实时聊天/ SKYPE/屏幕共享。
离开键盘
20.散散步。
21.打个盹。
22.重置优先级。暂时从键盘上离开还有一个好处就是可以让你重新评估这个问题的重要性,也许这个问题只是个CSS/布局问题,根本不值得你花上16个小时。总之要有效分配和使用时间。
23.暂时将这个问题放在一边。实在解决不了的话,可以将这个问题先搁置起来。也许几天后你在阅读相关问题的时候,突然一个激灵,解决问题的关键就来了。
隔离
24.确定是哪行代码。首先要确定是哪行代码导致的问题,以便于插入print语句。
25.将问题分割为一个单独的程序。有时候对于库和产品的问题,我们可以将它的相关代码从主程序中分离开来。这可能需要一点时间,但往往处理一个孤立的程序比应对整个的项目构建过程要容易得多。然后在解决这个单独程序的基础上再去和主程序作比较。
更改代码
即使你一点都不知道如何解决问题,更改代码也是一个挺有效的解决方法。
26.写新的单元测试。
27.重构。有问题的代码往往显得有点乱,通过一些简单的重构方法,例如重命名变量或展开嵌套的if / then/ else模块等都可以让代码整洁起来。
28.发现bug。另一个整洁代码的手段是查阅相关代码的“Find Bugs” 报告,我们之所以首先要整洁代码是因为:作为一个能让我们的大脑专注于代码的方法,既简单又划算。
29.重写。转存所有的相关代码,从头开始重写。一个全新的视角也许能让你完全规避这个问题。
30.为一些不必要的代码添加注释——或者至少是你以为是不必要的。然后你会发现可能这些代码流并不像你曾经以为的那样“没有必要”。
31.实验。如果你不能确定底层产品或库是如何工作的,那么一些小实验,特别是围绕边界条件的实验会非常有用。
32.回到干净的状态。如果你在代码中做了各种变动,或者是搞了很多配置设置,那么定期回到一个干净的状态就非常重要。否则,实验结果可能会影响正确答案,这样你就永远也找不到正确的解决方案了。
33.切换技术。
产品
34.升级到更高的版本。也许你正在处理的问题已经被修复了,可以试试先升级到另一个版本。
35.降级到以前的版本。也许问题正是由于与你目前正在使用的其他产品/库不兼容而引起的。
36.打补丁。
37.下载并安装源代码。
文件
38.阅读手册。大多数开发人员可能会认为这是一个低概率的策略,但是,嘿嘿,你永远不知道,也许答案就在文档中。
39.阅读手册的正确版本。
40.手册是否正确?有时候代码已被更新,但手册还没有。
调试器
41.了解键盘上的快捷键。
42.倒退。这是调试器的一个功能,让你的代码退后一步。
43.编写断点代码。
44.异常中断。调试器的一个蛮有用的功能就是可以捕捉到任何地方的特定异常。
45.专业化的调试工具。例如:
Plumbr
AppDynamics
Chronon
Wireshark
HTTP profilers:Fiddler2、Charles、Live Http Headers
源代码控制
46.对bug缺陷进行编号标记。你有没有碰到过这样的问题:先是用这种方式被修复了,然后几周后又成为了bug被其他人用另一种方法修复了。这样问题貌似就有两个正确答案。解决办法就是对源代码中相关的bug缺陷进行标记,并记录一些关于为何改变以及谁参与决策等更为详细的说明。
47.Blame功能。这个可爱的小工具能告诉你是谁最后更改的代码。
48.Git bisect功能。Git有一个有意思的“bisect”命令,能自动通过你提交的历史进行二进制搜索发现故障。
寻找答案
49.谷歌搜索。
50.论坛帖子。
52.搜索stackoverflow交流。
53.创建stackoverflow问题。
其他
54.聘请专家。可能在短时间内成本很高。
55.招实习生。聘请专家的相反方法就是聘请新手。有时候初学者饱满的热情能让他们从不同的角度来解决问题。
56.改变要求。如果你不能修复缺陷,那么可以改变要求。通过解释各种成本需要,也许能让客户改变他们的初衷。
57.更改上/下游系统。
58.循序渐进地学习技术。
59.通过断点检查配置。更改关键配置值,并确保已经断点,这样能够让我们无所顾忌地设置配置。
60.系统化。有时候我们需要将三四件事情组合在一起,那么可以将已经试过的组合记录下来,如果需要的话一定要尝试各种的组合。
原文链接:
- 60 Problem Solving Strategies[英文原文]
- 程序员解决问题的60个策略 – 极思维[翻译作者:极客网 – Lili]
《 “[collect]程序员解决问题的60个策略” 》 有 10 条评论
有哪些老鸟程序员知道而新手不知道的小技巧?
https://www.zhihu.com/question/36426051
为什么我们要阅读源码?
http://mp.weixin.qq.com/s?__biz=MzA3NDM0ODQwMw==&mid=2649827664&idx=1&sn=9d8570026349398fedb0aecd05dedc3b
如何阅读一份代码?
http://mp.weixin.qq.com/s?__biz=MzA3NDM0ODQwMw==&mid=2649827677&idx=1&sn=c50072121269e7d11fdf23bb7b76d95a
`
场景一:为了破案而阅读代码
场景二:为了明理而阅读代码
场景三:为了能级跃迁而阅读代码
`
如何写好一篇漏洞报告?
https://mp.weixin.qq.com/s/m5oO9-RNKiKWKMV-h0Qpng
如何有效地报告 Bug 中文删减版
https://github.com/w568w/How_To_Report_Bug_Properly
https://www.chiark.greenend.org.uk/~sgtatham/bugs.html
How to write a good bug report: step-by-step instructions
https://musescore.org/zh-hans/developers-handbook/how-write-good-bug-report-step-step-instructions
如何解决问题
http://javatar.iteye.com/blog/1617775
`
问题其实就是你期望的东西和你体验的东西之间的差别。
1)动手去解决问题之前,好好想想问题的来源;
2)如何站在各个角度来看待面临的问题,以能够知道其真正所在;如何去尝试那个最能解决真正问题的方法,并且时刻保持警惕心;
3)为什么不要把人们的解决方法误认为是问题的定义,更不要把某个问题的解决方法误认为是问题的定义,特别是这个解决方法是你自己所使用的;
4)永远都不要肯定自己已经有了一个正确的定义,即使是在问题好像已经解决之后;
5)每一种解决方法都会带来新的问题;
6)问题最难以处理的部分恰恰是去意识到它们的存在;
7)在理解问题之前,至少要做好准备接受三种可能的出错情况;
8)或许还可以改变问题的表述来获得不同的解决方法;
9)当你沉迷于寻找问题定义和解决方法时,不要忘记随时都回头看看,看看自己是不是已经迷路了……
10)当别人能够很好地解决自己问题的时候,千万不要越俎代庖;
11)如果某人能够解决这个问题,但是他本人却并不会遇到这一问题时,那么你首先要做的就是让他也感受到这一问题;
12)不管看上去如何,人们很少知道他们要什么,直到你给了他们所需要的东西;
13)甚至,事实上,并没有多少人真的希望他们的问题被解决。
真正的问题所在可能并不是您现在的所想,换个角度分析,或许您已经找到了问题的真谛。
`
在做程序员的道路上,你掌握了什么概念或技术使你感觉自我提升突飞猛进?
https://www.zhihu.com/question/68611994
怎样构建产品和技术之间的合作氛围
https://ppt.geekbang.org/slide/download?cid=25&pid=1147
产品经理 & 技术,如何组成一支特战小队
https://ppt.geekbang.org/slide/download?cid=25&pid=1150
如何像技术高手一样解决问题
https://toutiao.io/posts/a021q6/preview
https://paper.tuisec.win/detail/519426162404996
`
总结:直面问题,逢山开路,遇水搭桥。问题见的多了、解决的多了,自然也就成了高手。
如果在技术领域没遇到过什么难题(相对的)的话,只能证明你还涉世不深,高手一般都是填过无数的坑、踩过无数的bug的尸体走过来的,一帆风顺走过来的抗击打能力一般也会比较弱,一旦遇到坎就会熄火。
不逃避问题。虽然有时候会很棘手,可以绕过,如果有机会的话,还是要回头重新审视,看能不能找到对应方案,如果你真的有幸可以遇到一个前人都没有遇到的问题,真的可以去买彩票庆祝一下。在一个地方没有解决问题,在后面的职业生涯中它还会重新出现。
面对一个Bug,高手多半是凭猜测去解决问题,我这么说想必你有点不信。”我也猜了,为什么花了半天没猜对?”这就是经验多寡的差别,凭空无端猜测是不能解决问题的。经历的足够多,总结的足够多,思考的足够多,而这些都不会辜负你,他们会在有需要的时候闪现出来,下面要做的就是去验证这个猜测是否正确,如此循环,终究会找到那个”顿悟时刻”。
不要疏忽日志,很多问题的解法暴露在日志中。很多朋友在IDE的console中抛出一段异常后,习惯的clear干净,干净了也找不到应对之法了。有时候日志暴露过多,会让人找不到头绪,其实关键错误一般存在于一堆异常日志的最后一块中,前面的异常多半是这个根上的异常引起的。
遇到大问题时,学会分解。当面对一本大部头书时,你多半没信心读完。而拿着一本上百页的薄册子时完全不用担心读不完的问题。如果将大部头的书,拆解成N个几百页、几个主题来读,读完应该也不是什么难事,而不是永远束之高阁。要解决一个巨大的问题,分解后,就变成一个解决一个小问题就可以把大麻烦解决掉的套路,有”蚕食”想必更贴切一些。
有后盾在手,各种问题都不怕。一是自己的总结,二是网络中可以利用的资源,三是身边的人力资源。当前两个都失效的时候,平时积累的人脉就会发挥作用。许多人的脑容库总比一个人的大,所以有些问题总会有人之前遇到过,有相应的解决方案。从侧面也说明一个问题,如果一个问题自身无法解决,可以适当将风险抛出,寻求帮助,避免造成更坏的影响。
问题一直都有,看你是迎难而上还是畏缩不前?遇水搭桥、逢山开路,解决足够多的问题后,不成专家都难。
`
浅谈编码中的缩写
https://droidyue.com/blog/2019/05/26/abbreviation-do-not-make-me-think/
`
目前而言,几乎所有的编程语言都是使用英文来表示,在英文中,使用缩写很普遍,比如URL(Uniform Resource Locator)能够很简单高效地向他人阐述要表达的概念。
然而,在现实的开发过程中,缩写有时候会被滥用,甚至是脱离了其高效传递信息的意思。
什么是不好的缩写?
为什么要避免不好的缩写?
为什么会出现不好的缩写?
如何避免不好的书写?
当然避免的关键还是人的因素,针对上面的症结,需要做如下处理:
· 增强自身约束,认真对待,不随意缩写。
· 保持求索的态度,寻找更优解
· 学习英语,提升基本功。
随意缩写一时爽,后期维护泪千行。
`
值得程序员反复品味的编码智慧
https://mp.weixin.qq.com/s/fvCDYOCFsp0tdiwE6rmM8w
https://phauer.com/2020/wall-coding-wisdoms-quotes/
https://phauer.com/blog/2020/02-wall-coding-wisdoms-quotes/download/all-coding-quotes.pdf
`
不成熟的优化是万恶之源
优化的规则:
* 不要做!
* 再等等……时机未到。
* 优化之前先测量
作为程序员,永远不要低估你为简单问题提出异常复杂解决方案的能力。
先设计出正确的数据结构,余下的程序会自然而然地显露出来。
分布式计算第一法则:不要让你的计算分布!
至少在你还有机会避免的时候遵守这条法则。
可伸缩性。人类实际没法做到却一直试图解决的头等问题。(译注:不要同时做多件事)
共享 + 可更改 = 危险!
重复好过蹩脚的抽象。
* 避免不成熟的分布式。
* 避免不成熟的抽象。
两者都具有纯洁性、清晰性和可伸缩性的诱惑,但也增加了复杂性和运营/认知成本。
数据为王。
如果你已经选择了正确的数据结构并把数据组织得很好,算法几乎总是不言自明的。
数据结构是编程的核心,算法不是。
新人文技术价值观
自负 < 谦虚
精英主义 < 海纳百川
竞争 < 合作
投机取巧 < 专研学问
成为明星 DRY(避免重复)
`
程序员自我欺骗的9个瞬间
https://mp.weixin.qq.com/s/O5xOmk97_1attT-BtQwb0A
`
1. 算法不重要,会写程序能出活才是王道
2. 雄心勃勃列计划,觉得马上就能赢取白富美,走上人生巅峰了
3. 我把这个网页收藏起来,我就又多了一点知识
4. 这个bug我下班前改好
5. 买了网课后,就掌握了这门课程
6. 把这个任务完成,就可以下班休息了
7. 使用XX开源软件,可以解决我们的问题
8. 把书买了,这个内容我也就掌握了
9. 不要着急,你会有对象的
`