What most young programmers need to learn
In the past 7.5 years I have supervised over a dozen programming interns at Ronimo and have seen hundreds of portfolios of students and graduates. In almost all of those I saw the same things that they needed to learn. One might expect that I think they need to learn specific techniques, algorithms or math, or other forms of specific knowledge. And of course they do, but in my opinion that is never the main thing. The main thing they need to learn is self discipline. The discipline to always write the clearest code you can, the discipline to refactor code if it becomes muddy through changes later in development, the discipline to remove unused code and add comments.
Most of the time I spend supervising programming interns is spent on these topics. Not on explaining advanced technologies or the details of our engine, but on making them write better code in general. I always ask applicants what they think is important in being a good programmer and they usually answer that code should be clear, understandable and maintainable. That is indeed what I want to hear, but it is very rare for a young programmer to actually consistently follow through with that.
Keeping this in mind requires self discipline, because it means not stopping "when it works". If all the variables would have the wrong name the code could still function perfectly, but the code would be super confusing. The step from functional code to clear code brings very little reward in the short term: it worked already and after cleaning it up it still works. That is why discipline is required to take this step. That is also why doing an internship is so useful: a good supervisor is vigilant on code quality (even though the definition of "good code" might of course differ per programmer) and thus forces the intern or junior to always take that next step.
Let me give a few examples of the kinds of things I often see in code written by starting programmers:
Liar functions/variables/classes
These are functions, classes or variables that do something else than their name suggests. Their name is a lie. It is very obvious that names should be correct, but to my surprise it is quite common for names to be completely off.
An example I recently encountered in code written by a former intern was two classes: EditorGUI and EditorObjectCreatorGUI. This is code that handles the interface in our editors. To my surprise it turned out that the code that handled the button for creating new objects was in EditorGUI, while EditorObjectCreatorGUI only handled navigating through different objects. The exact opposite of what the naming suggests! Even though the code was relatively simple, it took me quite a while to understand it, simply because I started with a completely wrong assumption based on the class names. The solution in this case is really simple: rename EditorObjectCreatorGUI to EditorObjectNavigationGUI and it is already much, much more understandable.
This is something I see a lot: names that are simply incorrect. I think this often happens because code evolves while working on it. When the name was chosen it might have been correct, but by the time the code was finished it had become wrong. The trick is to constantly keep naming in mind. You have to always wonder whether what you are adding still fits the name of the function or class.
Muddy classes
Another problem I see is muddy classes: classes that do a lot of unrelated things. Again this is something that happens as you keep working on the same code. New features are added in the easiest spots and at some point classes become bloated with all kinds of unrelated behaviour. Sometimes the bloating is not even in the size of the classes: a class might be only a few hundred lines but still contain code that does not belong there.
An example of how this can happen is if for some reason a GUI class needs to analyse what textures are available (maybe because there is a button to select a texture). If the GUI class is the only class that needs the results of this analysis, then it makes sense to do that in the GUI class. However, then some totally unrelated gameplay class for some reason also needs that info. So you pass the GUI class to that gameplay class to query the texture information. At this point the GUI class has grown to be something more: it is also the TextureAnalyser class. The solution is simple: split off the TextureAnalyser class into a separate class that can be used by both the GUI class and the gameplay class.
The general rule of thumb to avoid this problem is to always wonder: does the functionality that I am adding here still fit the name of the class? If not, then the class either needs to be renamed, or it needs to be split into separate classes or the code needs to go into a different class.
It is usually a Bad Smell if you cannot come up with a fitting name for your class. If you cannot describe what a class does in its name, then maybe what it does is too muddy. It might need to be split into parts that make more sense and can actually be described with a proper name.
Oversized classes
This one is really similar to the muddy classes above: over time more and more is added to a class and it gets bloated. In this case however it all still makes sense to be in one class, but the class simply grows too big. Gigantic classes are cumbersome to work with. Bugs slip in easily as there is a lot of code manipulating the same private member variables, so there are a lot of details one can easily overlook.
Splitting a class that has grown too big is quite boring work. It can also be a challenge if the code in the class is highly intertwined. Add to this that it already works and that fixing it adds no new functionality. The result is again that it requires serious self discipline to split a class whenever it becomes too big.
As a general rule of thumb at Ronimo we try to keep classes below 500 lines and functions below 50 lines. Sometimes this is just not feasible or sensible, but in general whenever a class or function grows beyond that we look for ways to refactor and split it into smaller, more manageable pieces. (This makes me curious: where do you draw the line? Let me know in the comments!)
Code in comments
Almost all sample code that applicants send us contains pieces of code that have been commented out, without any information on why. Is this broken code that needs to be fixed? Old code that has been replaced? Why is that code there? When asked applicants are usually well aware that commented-out-code is confusing, but somehow they almost always have it in their code.
Parallel logic and code duplication
Another problem that I often see occurring is to have similar logic in several spots.
For example, maybe the name of a texture gives some information as to what it is intended for, like “TreeBackground.dds”. To know whether a texture can be used for a tree we check the filename to see whether it starts with the word “Tree”. Maybe with the SDK being used we can check that really quickly by just usingfilename.beginsWith(”Tree”). This code is so short that if we need it in various spots, we can just paste it there. Of course this is code duplication and everyone knows that code duplication should be avoided, but if the code being duplicated is so short, then it is tempting to just copy it instead. The problem we face here is obvious: maybe later the way we check whether a texture is fit for a tree changes. We then need to apply shotgun surgery and fix each spot separately.
A general rule of thumb here is that if code is very specific, then it should not be copied but put in a function. Even if it is super short and calling a function requires more code than doing it directly.
All of the things discussed in this blogpost are really obvious. Most of these things are even taught in first year at university. The challenge is to make the step from knowing them to actually spending the time to always follow through with them, to always keep them in mind. This is why the most important thing that all programming interns learn at Ronimo is not knowledge, but self discipline.
http://joostdevblog.blogspot.tw/2015/01/what-most-young-programmers-need-to.html
What most young programmers need to learn的更多相关文章
- Learn nodejs: Tutorials for Programmers of All Levels, 程序员每个阶段的示例
https://stackify.com/learn-nodejs-tutorials/ What is Node.js? Node.js can be defined as a dynamic, c ...
- [C1] Andrew Ng - AI For Everyone
About this Course AI is not only for engineers. If you want your organization to become better at us ...
- Go is more about software engineering than programming language research.
https://talks.golang.org/2012/splash.article Go at Google: Language Design in the Service of Softwar ...
- 转一篇关于Unity的PlayMaker
这篇文章转自http://va.lent.in/should-you-use-playmaker-in-production/ 此文作者大概深受其苦,吐槽了playmaker的多个蛋疼的地方,这其实说 ...
- 学习笔记之Fluent Python
Fluent Python by Luciano Ramalho https://learning.oreilly.com/library/view/fluent-python/97814919462 ...
- Learn golang: Top 30 Go Tutorials for Programmers Of All Levels
https://stackify.com/learn-go-tutorials/ What is Go Programming Language? Go, developed by Google in ...
- 10 Unit Testing and Automation Tools and Libraries Java Programmers Should Learn
转自:https://javarevisited.blogspot.com/2018/01/10-unit-testing-and-integration-tools-for-java-program ...
- Python 爬取所有51VOA网站的Learn a words文本及mp3音频
Python 爬取所有51VOA网站的Learn a words文本及mp3音频 #!/usr/bin/env python # -*- coding: utf-8 -*- #Python 爬取所有5 ...
- Learning How To Learn
1.Practice 2.memory every week for from working memory to long tern memory 3.sleep 4.running promote ...
随机推荐
- MATLAB作图方法与技巧(三)
1.利用指令plot绘制圆的参数方程x = sin(t),y = cos(t),(0<=t<=2*pi)的曲线图. 代码如下 t = linspace(0,2*pi,100); x = s ...
- Bootstrap模态框垂直居中展示的方法
在bootstrap.js中加入以下代码:
- 在Debian 9上安装和配置Observium网络监控
https://blog.csdn.net/csgd2000/article/details/80780697
- [bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑
5017: [Snoi2017]炸弹 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 608 Solved: 190[Submit][Status][ ...
- C# base64获取图片后缀
由于业务需要,使用的微服务,然后做的上传文件操作. 但是有个问题就是,如果上传的是图片,之前为了图省事儿,直接写后缀jpg,但是人总是要进步的嘛,然后抽空就找了个. 首先微服务相关就不介绍了,直接从引 ...
- Unable to connect to vulnerability scanner
问题: "Unable to connect to vulnerability scanner. If the system has been updated recently the ...
- Spring的自动装配
在Spring中对自定义的引用类型注入时可以实现自动赋值.但是必须依赖set方法: 自动装配功能有两种: <!-- autowire:"byType" --根据class匹 ...
- PreparedStatement 和 Statement 实现基本的批处理
批处理:若需要对数据库进行多步操作,则就没必要每次都和数据库进行一次通信,这样很消耗资源和时间.则需要将操作进行批处理: Statement方式来实现批处理 优点: ...
- HDU 6336.Problem E. Matrix from Arrays-子矩阵求和+规律+二维前缀和 (2018 Multi-University Training Contest 4 1005)
6336.Problem E. Matrix from Arrays 不想解释了,直接官方题解: 队友写了博客,我是水的他的代码 ------>HDU 6336 子矩阵求和 至于为什么是4倍的, ...
- Codeforces Round #124 (Div. 1) C. Paint Tree(极角排序)
C. Paint Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...