我怎样才能学会规划和推理来不平凡的编程问题的解决方案? [英] How can I learn to plan and reason about solutions to non-trivial programming problems?

查看:117
本文介绍了我怎样才能学会规划和推理来不平凡的编程问题的解决方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题被张贴,试图在相似的水平 HTTP的提问者提供工具和战略学习,程序员://stackoverflow.com/revisions/18104693/1



在特定情况下,提问者描述为自理稍微过去学习的Visual C#的新手阶段也作IT管理员不是一个专业的开发商。他们在很大程度上是自学成才作为一个程序员,不具备开发工作或技术的正式经历。然而,他们写使用Web,FTP,文件MANIP,音频几个体面复杂的实用程序(我的水平无论如何),以图形周围的玩弄和其他的Windows窗体的方法。我的问题是根据我自己的帮助解释他们需要:



我应该是程序员做的,谁写的程序和研究能力,学习关于和使用库,编程工具和语言,做成为一个有能力想出,评估与试验,选择和编程的问题?



实施完整的解决方案的

许多(大多数)我们对SO要么是专业开发人员或多产的业余爱好者设计的,而不是只有一个人谁知道如何编程。所以这个问题是问我们如何学会做我们每天做的事情。不过,我不是在寻找答案提供职业咨询,而是回答给出具体的知识和工具(包括学习工具和技术工具),它可以帮助这样的人的方法问题。



为了方便,我给原来的提问者的榜样的问题,这可能会帮助我们更具体地讨论他的更广泛的问题,因为大家都可以参照相同的例子。




具体的问题:经过多年的转换,传真和电子邮件公司已经创建了几个共享目录的相当混乱。主要用于学习和放大器;实践中,我想我会很快写一个程序,读取文件的目录,类似于以下内容:




  BkUpSalesReportJan2011(TXT).ZIP 
BkUpSalesReportJan2011(PDF).ZIP
BkUpSalesReportJan2011(DOC).ZIP
BkUpSalesReportFeb2011(TXT).ZIP
BkUpSalesReportMar2011(DOC)。拉链
BkUpSalesReportMar2011(PDF).ZIP
进入上几百个文件...




读取文件列表后,我要救唯一一个基于文件类型列表中的每个报告复印件(按优先顺序排列)。我想保持PDF文件,并删除所有副本。如果没有PDF文件,然后保存文档和最后保持TXTs。这是一个简单的例子,但这里是我总觉得不确定什么真正做到



的问题:我每个组的名称类似的文件添加到列表自己做一些字符串比较得到的结果,并立即删除?所有可删除的文件添加到另一个列表,并在整个目录已被处理删除吗?有没有一种方法对它们进行比较,同时开始阅读目录?它是最好创建一个小型数据库(我还不是很了解),并做一些不熟悉的数据库命令,得到的结果?有没有在Windows窗体埋的选择,我需要研究,这将奇迹般地为我做到这一点?我应该寻找那些需要照顾的这一切对我来说一些开源模块,代码或插件?我应该在错误的stackoverflow.com大乡亲这个可怕的简单困境?



解决方案

的在你需要发展自己的技能路线如下:




  1. 您需要加深您使用技术的知识
  2. 您需要从良好的伟大和糟糕的代码示例来学习。

  3. 您需要考虑其中使用你的代码的上下文。



前两个步骤是必要的,需要你作一个适当的程序员一个好。第三步是,我认为,有什么从开发程序员分开。如何重要的是你要看你的需要为您的工作,以及如何你想发展自己的技能。一个好的系统管理员,例如,几乎总是一个好的程序员,但并不需要是一个很好的开发者。



深化自己的知识



这意味着不必编程语言,程序库和系统的黑匣子的理解要能的如何的他们的工作。理想的情况是程序员,我们应该有这种类型的关于我们的系统的每一个层次的认识,从电,磁,通过CPU和计算机体系结构,操作系统原理(什么文件和进程,这两个伟大的操作系统抽象,真正对应),算法和CS数学,网络,图形和用户界面的东西,到编译器,像浏览器和编辑器等工具常用程序后面的代码。在实践中没有人能有足够的了解这一切,所以你必须要由双方来指导有什么有趣的你,什么是立即对你有用。



在例如给出以下所有可能会有所帮助更多的了解:当您移动或删除哪些磁盘上完全是一个文件或目录的代表和会发生什么;如何zip压缩工程;什么被存储在各种文件格式,以及如何。你能解决问题,而无需任何这些,但你需要知道所有的人,以确保你没有将更难比它的任务,否则就可能面临某种形式的数据丢失。



一个重要工具是事物了解的队列。正则表达式的答案,原来的问题很可能提及。有时什么似乎StackOverflow上,这是非常令人沮丧的贡献者发生,是有人问一个问题到正则表达式的答案。因为他们不理解正则表达式,他们选择一些劣质的解决方案,而不是了解他们。过了一会儿,他们回来问到正则表达式提供解决方案的另一个问题。再一次,他们更喜欢做一些不那么建议多学习新的东西。他们经常回来,并要求与他们的解决方法解决方案,他们将通过支出100内学正则表达式避免了复杂的帮助



队列的工作原理是这样的:首先你看到的东西你不知道关于SO提到,在教程中,或在一段代码,可以将其添加到列表中。你看到了第三次,你的有无的添加。你会发现关于这些东西基本的东西,读它,直到你了解他们。如果读数抛出了更多的东西,你不明白,你将它们添加到列表中。



另外一个好的规则来为自己是停止尽快阅读的东西,你发现你没有的任何的理解的术语。你查查那个东西,并确保你首先了解它。维基百科是这里你的朋友。



您会发现,你需要了解的事情有弹出的习惯。 '算法'是一个很好的例子 - 完全的中心到CS和软件。这里对您的问题将有太多的材料。从字面上有数以千计的书籍算法,包括博士层次的研究,等等。这个词是在许多不同的上下文中使用 - 算法交易,谷歌的算法或Netflix的算法',数学算法,等等看维基百科为算法,第一段是明确的,是有道理的页面,第二杆大多是可以理解的,但包含的东西你不需要知道,第三杆充满了技术细节是无关的初学者的。看完这整篇文章将是不可能的,浪费时间介于



所以,另一种工具;各种来源。如果事情是太困难了,找别的东西,读,第一。然后决定你是否需要阅读的头文件,别的东西更容易,或者说别的,这取决于你现在知道。尝试和学习需要进步最小,然后回去的东西更深入更高版本。您了解的正则表达式的第一次,你只要学会如何使用一个在你的代码。第二次,你看的特殊字符的列表,并尝试使用你不知道的人。第三次,你了解如何优化他们跑得更快。第四次,你了解他们背后的理论



另外一:挑选重要的和/或有趣的部分。如果你去 https://en.wikipedia.org/wiki/Algorithm#的部分'的例子 的例子,第一个例子是一个很好的起点。你有一个算法,该算法的描述,和一个伪代码(注意自我:仰视的伪代码的)实现。你能理解所有的人?图形是快速排序的可视化。是快速排序相同,在文本中的算法?你能理解的图形?您已经添加快速排序的东西来查找列表?第二个例子是最重要的算法之一永远,欧几里德算法的详细但易于解释。如果你花一个小时或一个晚上,最终还是不太了解的算法是什么,但知道什么是快速排序和欧几里德的算法,你绝对没有浪费你的时间。



在这里的另一个重要的工具是一种编程便笺:快速的编写和测试代码的一些方法。已经阅读快速排序或Euclid算法,你可以自己实现这些功能?你可以尝试一些其他的方法来解决同样的问题?你想尝试做一个GIF动画,如快速排序的图形?学习一正则表达式是什么,你可以写一些和测试,如果他们做什么他们认为你做的。作为一个C#程序员,你的选择包括:运行C#中的几行字瞬间像LinqPad工具(有网上的);保持模板各地迅速做出测试简单的事可执行文件;学习如Python附带的工具,即时评估代码片段另一种语言。



从例如学习



这是学习例如是真的,真的很重要。所有优秀的程序员都做到了,但很多书,特别是大学课程忽略它。你不通过例如,从片段学习的书籍以及所以,你需要真正的代码。



当比尔·盖茨是学习编程,他不得不鱼打印出来的在他的大学垃圾箱了解系统编程。可用的资源现在是无限的 - 有,而您可以阅读每一单件安装的代码整个服务器和桌面系统。这给了我们决定的新的问题的的代码来看看。



您可以在GitHub上或sourceforge上寻找东西,你有兴趣并尝试运行它们。这种方法的缺点是,它可能不是很好的代码 - 你可能无法分辨好坏代码



综观工具,尤其是小工具,其中有社会认可度的好方法。有哪些做简单的事情,哪些是开源的各种常见的.NET库。而不是推荐一些,最好用,因为你要从代码中调用它,你遇到的人。请确保你知道你试着学习源之前,如何使用图书馆。如果你使用Linux或其他自由报操作系统,挑你日常使用学习工具之一。如果你不这样做,安装的东西开源,并试图研究代码之前使用它一下。



做的基本的东西只是一个拿一个单一的文件直到你明白它做什么阅读。这可能涉及到首先选择几个文件,你丢弃,因为它们过于抽象/太复杂/太难。 (如果你不取得进展,不要害怕找到一个完全不同的项目,有些代码编写,并评论到被外人理解,有些则不是。)这肯定会涉及直读的一定量(也许对纸,所以你可以做笔记),一些仰视的东西,你不明白,和一个IDE一些阅读在这里你可以轻弹来回函数调用之间。



你学习的程序应该尽可能小而简单越好。如果你尝试看看Firefox的代码,你将有发现,做一些事情理解你的位之前通过目录和接口拖网。



免费软件有时会麻烦来构建,因为依赖。你不必能够编译它,研究它,特别是如果你想知道一点点如何做一些事情。但它确实有所作为,因为你能够改变的事情,看看会发生什么。最起码,你将能够打破它,然后试着了解为什么它打破了。



在计算器上更长的答案可能是有用的,特别是如果你不只是看他们提取解决您的具体问题。如果您至少有一个功能齐全,最好是一个类,试图检查与该代码编写的风格。这是更深比格式更有趣。是功能比你写的函数短或更大?是否有更多或更少的中间变量?是内置的或使用的第三方库,你不知道? (其中添加的东西来查找队列)你了解泛型,扩展方法,运营商,集装箱或LINQ在回答中使用?他们使用的评论你的方式?什么意见补充的吗?



有关SO和类似的另一好处是,如果你不明白为什么海报做了一些方法你可以问他们。大多数人会受宠若惊仔细阅读他们的代码。如果你认为你可以简化或更正代码,这样做。如果你听错了,你通常会明白为什么它的工作原理是特定的方式,这会为别人谁可能犯同样的错误,你增加价值的解释。



从其他语言阅读的代码。你可能不能够编写的Hello World用Pyt​​hon,C或方案,但你能理解吗?这是一个有用的技能也将帮助您找到您想了解下一个语言。 http://rosettacode.org 是一个独特而迷人的资源。



阅读代码的制胜法宝是寻找一种已被广泛评论和/或在单独的文档注释实际的工作代码,为了通过学习程序员阅读。没有了很多本。幸运的是,有一个很大的例外 - C#神@JonSkeet写重新实现的LINQ to Objects的一系列博客文章作为例子解释了LINQ和还介绍了如何设计良好的,可靠的代码计划,并提出

当你是一个更好的编码器,你就可以看坏的代码,看看为什么它是坏的。这是一个很好的学习工具,因为在世界上很多不好的代码!再次,启动与SO - 如果有人请求帮助,一段代码,他们可能写的东西,你可以帮助改善



编码上下文



回过头来看看这个例子。如果有人在我的工作要求我写这篇文章,我的第一个问题是 - ?这是不是我们会做一次以上



假如答案是没有了,我相信答案。然后我会很快合理而能够完成任务写东西。如果这是一个有点慢,不应该对我很重要,只要它是可行的运行它。而无需担心文件的安全性,我可能会备份整个目录,运行程序,然后检查,没有什么得到了捣毁。如果那样,恢复备份和重新开始。



假如答案是肯定的。或者,假设答案是否定的,但我怀疑,在一年的时间,他们会要我再写同样的事情(第1课 - 用户并不总是知道他们需要什么)现在,我是一个软件开发人员,以及我需要考虑很多事情之前,我写什么。



谁来运行代码?这将是人谁知道他们在做什么?什么接口他们会坦然面对?他们将如何知道这些代码已经正常运行?诀窍是想象用户,谁不知道或关心的语言,设计或背景,并设法找出程序工作,或以各种方式行不通时,他们会认为。即使的的是用户,你仍然需要想象自己在一个不同的上下文。当文件服务器不工作,因为磁盘已满,并且要运行你的工具,你会不会想打开Visual Studio改变的事情,还是要弄清楚它是如何工作的。你会希望它已被设计为工作,你希望它太的方式。



什么是它可以运行不同的方式?将在运行时提供什么样的输入或参数?他们将如何提供?用户如何知道如何提供呢?最后一个问题触及了开发商一个很大的话题 - 文档。我们写一个小脚本时的本能是我们不希望写一封长手动去用它。但该方案可以例如显示其选项列表。如果它总是这样做,当记者问时,或选项是错误的?几乎不存在的代码,不需要任何评论,也应该有几乎没有任何程序,不需要任何文件。



有哪些不同的方式程序能完成?怎么会错呢?其中这些错误防止它在所有做什么?它将如何沟通错误?它记录警告和'近错误?它记录正常行为?一个重要的设计技术是故障安全 - 现在是一个经常被误用的表达。这并不意味着从失败的安全,这意味着在一个安全的方式失败。在这个例子中,这意味着,如果有任何错误或不确定,请不要删除任何东西。



不再是一会儿一个程序员,做一个测试。 (乔尔在软件,这是充满了关于开发有趣和一般伟大的东西,这里测试会谈 HTTP: //www.joelonsoftware.com/articles/fog0000000067.html )。尝试和突破你的程序。给它的输入错误,试图找到它不会给你正确报告,试图使它做的事情,不应该(如错误删除文件)错误。你必须尝试和思考一切可能出问题的,系统管理员的东西都是平时不错。你没有发现的错误是,当他们在生产中发生,会被发现的人。



现在你正在考虑设计的软件,而不是写一个程序,你需要思考未来。当需求变化(第2课 - 要求随时改变),谁去适应旧版本?是老版本将仍然可以使用?将新版本包含旧的所有功能?



有一件事你将不得不做的是使后面的幕后变化不影响程序是如何工作的。你将不得不做的另一件事是改变功能。在第一种情况下,你必须确保你知道它究竟是如何做的工作,包括用户是依靠什么样的行为。在第二种情况下,必须能够改变传达给用户。这些是,例如任务。微软大概一半献给他们的发展资源。



获取混帐,并用它做检出,分支,合并与自己的项目。学习使用它已经将帮助您了解如何开发人员思考和工作。



在这里,你可以学习的榜样了。请记住,不够好学习和借鉴这些代码GitHub的项目?那么得到持续发展是足够受欢迎的人现在越来越好,而且渐入佳境的过程是一样的代码本身一样重要。克隆一个仓库,并按照补丁和更新日志。除了学习如何与这些在Git中处理,你将是继一期工程进展如何,假的开始和未来的目标。 (第3课 - 所有项目都将被从地上爬起来,在未来的版本重写')



任何合理的大开源项目可能有一个邮件列表归档。第一视线它的全闲聊和重复的,但是这是真正的工作要做开发商。他们通过不同的缺陷,功能和外观设计一次又一次地捶打出来做事的最佳方式。可以说,做出这个决定是相对于编写实际的代码最困难的部分。在这些讨论中每个人都试图找到重要的边缘情况影响的设计,试图预测将取决于性能,试图找出什么样的变化可能需要在未来作出。这个问题的答案决定一切,你是苦苦思索,比如是否使用第三方库与否,都可以在这里找到。他们的决定并不适用于你,但这些决定达成的方式是你应该学习的东西。



回去做一个测试,看看你是否能打破别人的代码。开源项目更是出奇地强劲。看看,找出为什么会是这样。他们是如何解析选项,这样糟糕选项不会使代码摔倒了像你这样的呢?他们在哪里检查错误?例外情况是如何处理的?还有什么是内部完成的,以表示该代码的一部分不能工作吧?



当你准备好了,你会希望做一个补丁,并将其发送在合并。对于一个流行的开源工具,直到你明白这个项目的编码风格,和维护者把它的方向的架构,你会不会做好准备。对于在GitHub上一个爱好的项目,你也许可以发送更多的试探性的东西。一旦你的补丁被接受或拒绝,试着了解为什么。你可以重写它适合在较好?维护者为什么要以不同的方式做的事情?他们怎么会结合你的建议(如果有的话)?



最后



不要试图做这一切的一次。使你想要做的事情的清单,然后回来给它。不要担心太多事你开始,没有完成,只要你完成的东西。如果你发现你强迫自己去学习你发现无聊之极的东西,尝试移动到别的东西。我们这样做,因为它的乐趣!


This question was posted in an attempt to provide tools and strategies for learning, to a programmer at a similar level to the asker of http://stackoverflow.com/revisions/18104693/1

The questioner in that specific case describes themself as "slightly past the newbie stage of learning Visual C#" but also as "an IT Administrator not a professional developer". They are largely self-taught as a programmer and do not have formal experience of development work or techniques. However, they have "written a few respectably complex utilities (for my level anyway) using web, ftp, file manip, audio, toyed around with graphics and other Windows Forms methods". My question is based on my own interpretation of the help they need:

What should a programmer do, who has the ability to write programs and to research, learn about and use libraries, programming tools and languages, do to become capable of coming up with, evaluating, experimenting with, choosing and implementing complete solutions to programming problems?

Many (most) of us on SO are either professional developers or prolific hobbyist developers, as opposed to someone who knows only how to program. So this question is asking us how to learn to do the things we do every day. However, I'm not looking for answers giving career advice, but rather answers giving specific knowledge and tools (both tools for learning and technological tools) which can help someone approach problems in this way.

For convenience, I give the original asker's example problem, which might help us discuss his wider problem more concretely, since we can all refer to the same example.

The Specific Problem: Through years of converting, faxing and emailing our company has created quite a mess of a few shared directories. Mostly for learning & practice, I thought I would quickly write a program that reads a directory of files that looks similar to the following:

BkUpSalesReportJan2011(txt).zip
BkUpSalesReportJan2011(pdf).zip
BkUpSalesReportJan2011(doc).zip
BkUpSalesReportFeb2011(txt).zip
BkUpSalesReportMar2011(doc).zip
BkUpSalesReportMar2011(pdf).zip
Goes on for a few hundred more files...

After reading the file list, I want to save only one copy of each report based on a list of the file types (in order of priority). I wanted to keep PDFs and delete all the duplicates. If there were no PDFs then keep DOCs and lastly keep the TXTs. This is a simple example but here is where I always feel unsure about what to actually do.

The Questions: Do I add each group of similarly named files to a list of their own and do some string comparisons to get the results and delete immediately? Add all the deletable files to another list and delete when the entire directory has been processed? Is there a way to compare them while initially reading the directory? Is it better to create a small database (which I know very little about) and do some unfamiliar database commands to get the results? Is there a buried option in Windows Forms I need to research that will magically do this for me? Should I just look for some open source module, code or plugin that takes care of all this for me? Should I bug the great folks at stackoverflow.com with this horribly simple dilemma?

解决方案

The directions in which you need to develop your skills are as follows:

  1. You need to deepen your knowledge of the technologies you use.
  2. You need to learn from examples of good, great and bad code.
  3. You need to consider the context in which your code is used.

The first two steps are essential and take you from being an adequate programmer to a good one. The third step is, I would argue, what separates a programmer from a developer. How important it is to you depends on what you need for your work and how you want to develop your skills. A good sysadmin, for example, is almost always a good programmer, but doesn't need to be a good developer.

Deepening your knowledge

This means going from having a 'black box' understanding of programming languages, programs, libraries and systems to being able to how they work. Ideally as programmers we should have knowledge of this type about every level of our systems, from electricity and magnetism, through CPU and computer architecture, operating systems theory (what files and processes, the two great OS abstractions, really correspond to), algorithms and CS math, networking, graphics and user interface stuff, to the code behind compilers, common programs like browsers and editors, and other tools. In practice no-one can know enough about all of this, so you have to be guided by both what's interesting to you and what is immediately useful to you.

In the example given, all of the following might have been helpful to know more about: what exactly a file or directory on disk represents and what happens when you move or delete it; how zip compression works; what is stored in the various file formats and how. You can solve the problem without any of these, but you need to know about all of them to be sure that you're not making the task much harder than it is, or risking some form of data loss.

One important tool is a queue of things to learn about. Regexes were probably mentioned in the answer to the original question. What sometimes seems to happen on StackOverflow, which can be very frustrating to contributors, is that someone asks a question to which regexes are the answer. Because they don't understand regexes, they choose some inferior solution rather than learn about them. A little later they are back asking another question to which regexes provide a solution. Yet again they prefer to do something less well recommended than to learn something new. Often they come back and ask for help with the complexities of their workaround solution, which they would have avoided by spending 10 minutes learning regexes.

The queue works something like this: the first you see something you don't know about mentioned in on SO, in a tutorial, or in a piece of code, you can add it to the list. The third time you see it you have to add it. You find something basic on each of these things and read it until you understand them. If reading throws up more things you don't understand, you add them to the list.

Another good rule to make for yourself is to stop reading something as soon as you find a term you don't have any understanding of. You look up that thing and make sure you understand it first. Wikipedia is your friend here.

You will find that the things you need to know about have a habit of popping up. 'Algorithms' is a great example - completely central to CS and software. Here your problem will be that there is too much material. There are literally thousands of books on algorithms, including PhD-level research, etc. The word is use in lots of different contexts - algorithmic trading, 'Google's algorithm' or the 'Netflix algorithm', mathematical algorithms, etc. Looking at the Wikipedia page for 'Algorithm', the first paragraph is clear and makes sense, the second par is mostly comprehensible, but contains things you don't need to know, and the third par is full of technical detail which is irrelevant to a beginner. Reading this whole article would be somewhere in between impossible and a waste of time.

So another tool; a variety of sources. If something is too difficult, find something else, read that first. Then decide whether you need to read the first document, something else easier, or nothing else, depending on what you now know. Try and learn the minimum necessary to progress, then go back to things in more depth later. The first time you learn about regexes, you just learn how to use one in your code. The second time, you look at a list of special characters and try and use the ones you don't know. The third time, you learn about optimising them to run faster. The fourth time, you find out about the theory behind them.

Another one: pick the important and/or interesting parts. If you go the section 'Examples' of https://en.wikipedia.org/wiki/Algorithm#Examples , the first example is a great starting place. You have an algorithm, a description of that algorithm, and a pseudocode (Note to self: look up pseudocode) implementation. Can you understand all of them? The graphic is a visualization of quicksort. Is quicksort the same as the algorithm in the text? Can you understand the graphic? Have you added quicksort to the list of things to look up? The second example is a detailed yet accessible explanation of one of the most important algorithms ever, Euclid's algorithm. If you spend an hour or an evening, and end up still not knowing quite what an algorithm is, but knowing what quicksort and Euclid's algorithm are, you definitely haven't wasted your time.

Another essential tool here is a programming scratch pad: some way of writing and testing code quickly. Having read about quicksort or Euclid's algorithm, can you implement them yourself? Can you try some other method to solve the same problem? Do you want to try and make an animated gif like the quicksort graphic? Having learnt what a regex is, can you write a few and test if they do what they think you do. As a C# programmer, your options include: a tool like LinqPad for running a few lines of C# instantly (there are online ones); keeping templates around to quickly make executables that test simple things; learning another language like Python which comes with tools to instantly evaluate code snippets.

Learning from example

Learning from example is really, really important. All good programmers have done it, yet many books and especially college course ignore it. You don't learn by example from snippets in books and on SO, you need real code.

When Bill Gates was learning to program, he had to fish printouts out of a dumpster at his college to learn about systems programming. The resources available now are limitless - there are whole server and desktop systems for which you can read every single piece of installed code. This gives us the new problem of deciding which code to look at.

You can go searching on gitHub or sourceforge for things that you are interested in and try to run them. The downside of this is that it might not be very good code - and you might not be able to tell good code from bad.

Looking at tools, especially small tools, which have community acceptance is a good way. There are various common .Net libraries which do simple things and which are open source. Rather than recommend some, it's best to use the one that you come across because you want to call it from your code. Make sure that you know how use the library before you try to study the source. If you use Linux or another libre operating system, pick one of the tools you use everyday to study. If you don't, install something open source and use it a bit before trying to study the code.

The basic thing to do is just a to take a single file and read it until you understand what it does. This probably involves choosing a couple of files first that you discard because they are too abstract/too complex/too difficult. (Don't be scared to find a whole different project if you don't make headway. Some code is written and commented to be understood by outsiders and some isn't.) It will certainly involve some amount of straight reading (maybe on paper so you can make notes), some looking up of things you don't understand, and some reading in an IDE where you can flick back and forth between function calls.

The program you study should be as small and simple as possible. If you try to look at the Firefox code, you will have to trawl through directories and interfaces before finding the bit that does something comprehensible to you.

Free software can sometimes be a hassle to build because of dependencies. You don't have to be able to compile it to study it, especially if you want to know how a little bit of it does something. But it does make a difference, because you will be able to change things and see what happens. At the very least, you will be able to break it, then try and understand why it broke.

Longer answers on StackOverflow can be useful, especially if you don't just look at them to extract the solution to your particular problem. If you have at least a complete function, preferably a class, try to examine the 'style' with which the code is written. This is much deeper and more interesting than formatting. Are the functions shorter or bigger than the functions you write? Are there more or fewer intermediate variables? Are built-in or third-party libraries used which you don't know about? (Add them to the queue of things to look up) Do you understand how generics, extension methods, operators, containers or LINQ were used in the answer? Do they use comments the way you do? What do the comments add?

The other nice thing about SO and similar is that if you don't understand why the poster did something some way you can ask them. Most people will be flattered that you read their code carefully. If you think you can simplify or correct the code, do so. If you got it wrong, you'll usually get an explanation of why it works that specific way, which will add value for others who might make the same mistake as you.

Read code from other languages. You might not be able to write Hello World in Python, C, or Scheme, but can you understand it? This is a useful skill which will also help you find the next language you want to learn. http://rosettacode.org is a unique and fascinating resource.

The holy grail of reading code is to find actual working code which has been commented extensively and/or annotated in a separate document, in order to be read by learning programmers. There isn't a lot of this. Luckily, there is a great exception - C# god @JonSkeet has written 'Reimplementing LINQ to Objects' as a series of blog posts which explains Linq by example and also shows you how well-designed, robust code is planned and made.

When you're a better coder, you will be able to look at bad code and see why it is bad. This is a great learning tool because there is a lot of bad code in the world! Again, start with SO - if someone is asking for help with a piece of code, they probably have written something that you could help to improve.

Coding in context

Going back to the example. If someone in my workplace asked me to write this, my first question would be - "Is this something we are going to do more than once?"

Suppose the answer is no, and I believe the answer. Then I would write something reasonably quickly which gets the job done. If it is a little slow, that shouldn't matter to me, as long as it is practical to run it. Rather than worry about the safety of files, I might backup the whole directory, run the program, and then check that nothing got trashed. If it did, restore the backup and start again.

Suppose the answer is yes. Or suppose that the answer is no, but I suspect that in a year, they will want me to write the same thing again (Lesson 1 - users don't always know what they need.) Now I'm a software developer, and I need to think about a lot of things before I write anything.

Who will run the code? Will it be someone who knows what they are doing? What interface will they be comfortable with? How will they know that the code has run properly? The trick is to imagine being the user, who doesn't know or care about the language, the design or the background, and try and figure out what they will think when the program works or doesn't work in various ways. Even if you are the user, you still need to imagine being yourself in a different context. When the file server isn't working because the disk is full, and you want to run your tool, you won't want to open Visual Studio to change things, or to figure out how it works. You will want it to already be designed to work the way you want it too.

What are the different ways it could be run? What inputs or parameters will be provided at runtime? How will they be provided? How will the user know how to provide them? The last question touched on a huge topic for developers - documentation. Our instinct when writing a small script is that we don't want to write a long manual to go with it. But the program can for example display a list of its options. Should it do this always, when asked, or when the options are wrong? There is almost no code that doesn't need any comments, likewise there should be almost no programs that don't need any documentation.

What are the different ways the program could complete? What could go wrong? Which of these errors prevent it from doing anything at all? How will it communicate errors? Does it log warnings and 'near-errors'? Does it log normal behavior? An important design technique is 'fail-safe' - now a frequently misused expression. It doesn't mean safe from failure, it means 'fails in a safe way'. In the example, this means that if there is any error or uncertainty, DON'T delete anything.

Stop being a programmer for a while and be a tester. (Joel On Software, which is full of interesting and generally great stuff about development, talks about testers here http://www.joelonsoftware.com/articles/fog0000000067.html). Try and break your program. Give it the wrong inputs, try and find errors that it doesn't report to you properly, try and make it do things that it shouldn't (like delete the wrong files). You have to try and think of everything that could possibly go wrong, something sysadmins are usually good at. The errors that you don't find are the ones that will be found when they happen in production.

Now you are thinking about designing software, rather than writing a program, you need to think about the future. When the requirements change (Lesson 2 - the requirements always change), who is going to adapt the old version? Is the old version going to still be used? Will the new version contain all the functionality of the old one?

One thing you are going to have to do is make behind-the-scenes changes that don't affect how the program works. The other thing you are going to have to do is change the functionality. In the first case you have to make sure you know exactly how it does work, including what behavior the users are relying on. In the second case you have to be able to communicate the changes to the users. These are tasks that eg. Microsoft probably dedicate half their development resources to.

Get git and use it to do checkouts, branches, merges with your own projects. Learning to use it will already help you understand how developers think and work.

Here you can learn by example too. Remember those GitHub projects that weren't good enough to learn code from? Well the ones that are popular enough to get continuously developed are now getting better, and the process of getting better is just as important as the code itself. Clone a repository and follow the patches and changelogs. As well as learning how deal with these in Git, you will be following how a project progresses, the false starts and future goals. (Lesson 3 - all projects are 'going to be rewritten from the ground up in the next version')

Any reasonably big open source project probably has a mailing list archive. A first sight it's full of chitchat and repetition, but this is the real work developers do. They go through different bugs, features and designs again and again to thrash out the best way of doing things. Arguably making this decision is the hard part compared to writing the actual code. In these discussions everyone is trying to find the important edge cases which affect the design, trying to predict what performance will depend on, trying to figure out what changes might need to be made in the future. The answer to all the decisions that you are agonizing over, like whether to use third-party libraries or not, can be found here. Their decisions don't apply to you, but the way those decisions are reached is what you should be studying.

Go back to being a tester and see if you can break someone else's code. Open source projects can be surprisingly robust. Look and find out why this is so. How are they parsing options so that bad options don't make the code fall over like yours does? Where are they checking for errors? How are exceptions handled? What else is done internally to signal that one part of the code can't work right?

When you're ready, you will want to do a patch and send it to be merged in. For a popular open source tool, you won't be ready until you understand the architecture of the project, the coding style, and the direction the maintainers are taking it. For a hobby project on GitHub, you can probably send much more tentative things. Once your patch gets accepted or rejected, try and understand why. Can you rewrite it to fit in better? Why do the maintainers want to do things differently? How did they end up incorporating your suggestion (if at all)?

Finally

Don't try to do all of this at once. Make a list of things you want to do, and come back to it. Don't worry too much about things you start and don't finish, as long as you finish something. And if you find that you're forcing yourself to learn something you find excruciatingly boring, try moving onto something else. We do it because it's fun!

这篇关于我怎样才能学会规划和推理来不平凡的编程问题的解决方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆