今日推荐英文原文：《How to be a great programmer》
推荐理由：一个关于计算机历史的资源合集。这里面的大部分资源都是 20 世纪时候的东西了，你能在这里面发现我们现在熟知的 TCP/IP，UTF-8，命令行以及现在常用的 ping 命令等等，有的时候知道这些常用玩意儿的历史也是个挺有意思的事情。
今日推荐英文原文：《How to be a great programmer》作者：Amy M Haddad
How to be a great programmerAs we all know, great programmers build amazing features, websites, apps, and the like. But what do they have in common?
In my research, it’s not just about knowing a language really well or having a particular educational background. It’s that the really talented programmers have mastered the fundamentals. That foundation is what enables them to build great things and come up with breakthrough ideas.
Think of a pyramid. It has a large base, but gradually gets smaller and thinner toward the top. Learning the fundamentals of programming forms that base. Everything takes off from there.
So what are those fundamentals? Based on my experience and the programmers whose backgrounds I’ve researched, I see programming fundamentals as a two-part approach.
Problem Solver ExtraordinaireFirst, you have to be an effective problem solver. This is an important place to start since programming is problem-solving.
Although there are many ways to solve a problem, there are a few parts of the process that stand out to me. Programmers who are also great problem solvers distill a problem to its essence, in order to identify their overall aim and begin a problem with purpose. Then, they break each problem into small, manageable parts — attacking each part in turn, and sometimes in visual terms by drawing a picture to make it “real world.”
The process is harder than it sounds. When I started to program, I hit a wall: like many others, I never learned how to problem solve in school; it’s a skill that’s not readily taught. I was given a problem set in math class and just dove in, which is what I did when I started to program. Unsurprisingly, I was spinning my wheels unnecessarily and hitting roadblocks on the simplest of problems.
Things began to change when I began learning about the problem solving process, and how to problem solve effectively. I now begin a problem with intent. I have George Polya’s book, How to Solve It, to thank for that bit of advice.
I’ve adapted some of Polya’s ideas to programming, like understanding the problem. “The problem must be understood,” Polya writes. This includes being able to “point out the principal parts of the problem, the unknown, the data and the condition.” For each problem, I pull out a sheet of paper and write answers to these questions: what am I solving for or trying to find? (unknown); what am I given? (data); and what constraints or details do I need to be aware of? (condition).
Understanding the problem may seem obvious, but the obvious is easily overlooked. On more than one occasion, I’ve poured hours into a problem only to realize much later that I missed a small, but critical detail in the problem statement. Writing out problem details slows me down mentally, and helps me think through exactly what I need to do, which is half of the battle.
From there, I make a plan, which is another of Polya’s suggestions. It makes sense. I write an outline before I write an article. An artist makes a sketch of the painting before working on the painting itself. A builder uses drawings and blueprints to build a house. It’s no different with programming. Instead of rushing into doing, I need to start by thinking about what I’m setting out to do and make a plan of attack.
There are many ways to go about this. Sometimes I outline the steps I need to take in numerical order: first do this, second do that. Other times I make the problem visual. When I was learning about for loops, I pulled out a handful of almonds and physically iterated through the pile. It’s a silly example, but it helped me think through the problem.
I’ll also draw pictures or diagrams. For a recursive problem, I’ll draw a diagram of what’s happening on each recursive call until I hit the base case. Almost always, however, I find a way to simplify the problem to make it more manageable and to help me spot a pattern. Above all, the aim for me is to enter a problem with purpose, and maintain that sense of purpose throughout.
Despite the best made plans, problems are still hard and I still get stuck. Becoming a great problem solver takes time; it’s a skill I’m still working on and it’s definitely worth the effort. It’s a difference you can see.
When I read code written by a great problem solver, it’s clean and easy to understand. Variables are well named. Functions are short and crisp. Each line of code has a specific purpose; the fluff is removed. The clarity of the code mirrors the programmer’s thought-process: I can read the program from top to bottom and know exactly what’s going on. That’s great problem solving, and that’s what I’m striving for.
What about your Computer?Learning computer science is the second programming fundamental. I recently started learning computer science, and love it because I’m moving beyond surface level. I’m going “behind the scenes” to learn what happens when I use a built-in function, for example. I’m also learning about memory and run time, among many other topics. In short, I’m learning why a computer does the things it does.
Knowing the “why” enhances my contextual knowledge and makes me a more informed programmer. As a result, I’m more thoughtful with the code I write. Now that I know a bit about run time, for instance, I’ll opt to use a binary search instead of iterating through each element in a list.
It’s also enriching my understanding of how core programming concepts work. For example, I was working on a recursive problem and I wasn’t getting the solution I anticipated. After close examination, I learned why: it had to do with the execution of the call stack, an idea that would’ve escaped me just a few months ago.
Or take classes. I struggled immensely with classes for the longest time, and was terrified to use one. I knew how to write a class, but wasn’t confident when and why I’d use one. That changed when I learned what actually happens in my computer when I create instances and call methods. It finally clicked, once I had some context. For both recursion and classes, computer science bridged gaps in my knowledge.
All too often, the fundamentals get pushed aside. Progress can be slow, and people tend to pick more “fun” stuff to work on when given the option. That’s a shame. Programmers who master the fundamentals seem to code with confidence: they know the “how” and “why” of their programming choices, which improves their work and builds their credibility with others.
Plus, a solid grasp of the fundamentals makes learning new languages and technologies easier to do. For example, taking the time to really understand core concepts like iteration, recursion, and abstraction with one language will help when learning another. Simply put, there’s a lot to gain and little to lose by mastering the fundamentals.