I’ve been doing pair programming for a long time to support people who are not very good at programming. I will summarize the bad habits I noticed and the good habits for growth.

Power of habit

I’ve always wondered what determines the power of programming. Some people are good at learning, some people are bad. It’s easy to call these things “sense” and discard them, but I thought there might be factors that determine these things apart from whether one’s brain is good or bad.

A few years ago, I had an epiphany when I looked at my colleague’s screen next to me or the various engineers in my office. For some reason, I felt that the lower the output speed, the more likely the “stack trace screen output by the web application framework” would be displayed.

I’m not keeping statistics on this, so I can’t say for sure, but my colleague’s development cycle next to him went something like this:

  • Write code
  • Save code
  • Switch the screen to the browser
  • To reload
  • An error screen is an output
  • Immediately return to the code screen

I thought this was very inefficient. He wrote the implementation of the part close to the model layer (although the processing was written in the controller as a matter of course).

In no time, I taught them how to “check syntax” and “run modules on screen.” I also taught “how to write a small test code” using it. When I asked him why, he was at a loss for an answer. He said, “Since the screen will be displayed in the end, it will be closer to completion if you look at the screen.’’

It was a matter of habit. At that time, there was no CI in our system. Many engineers were not in the habit of writing tests.

After that, CI was introduced, and writing test code became a necessity, and after confirming that it worked on the browser, he was writing tests without much trouble.

The confirmation cycle was long, and the problem was only compounded by the fact that it had been merged, and the error message was output. I didn’t read much, so maybe I didn’t care.

The degree of cohesion of the code was high, and the difficulty of the test increased, probably because I wrote the test without being conscious of the unit test. Even systems designed to support productivity ended up undermining productivity through bad habits.

Bad habit

Recently, I’ve been doing pair programming with a few young engineers. It is touched for a relatively long time on a scale of several hours a day. I will introduce the bad habits I have pointed out or discovered.

Low code reading ratio

In programming, the percentage of code reading tends to be high, depending on the type of project. Some things are 80% reading and 20% writing. Code reading is necessary to understand the framework, peripheral code, and essential parts.

However, in the case of engineers whose output is stagnant, the ratio of the act of reading the source is meager. For example, I’m trying to use some framework features, but the result is not working correctly. The framework side’s error message told me it was an invalid input. However, he did not read the corresponding part of the framework.

So what are you doing?

  • Look at what you have written and vaguely search for mistakes
  • Vaguely see the copy-and-paste source code that seems to work correctly

That’s what I was doing. And when he didn’t understand, his style was to ask himself what was wrong with this.

How to improve

I taught how to find the corresponding code of the framework and made it possible to find it. So I asked them to read their actions to see why my code wasn’t working.

Psychological problems

When I asked why he didn’t look into the framework code, he replied, “Because it seems difficult. I want to finish it quickly.” Frameworks are becoming more complicated, and there are places where it’s difficult to grasp the whole.

However, as you read it, you will understand the language functions and libraries, and your knowledge will expand. Getting rid of this psychological resistance and reading the code to solve the problem quickly is essential.

Therefore, it is also essential for mentors not to give instructions such as “You don’t have to understand this’’ or “Just move it without reading it’’. I suspect that the depth of digging into the code is a fundamental parameter of the limits of programmer growth.

Do not check for small cycles

As with the very first example of the power of habit, it’s important to have the fastest confirmation cycle possible. In other words, it is also automated in the end.

It wasn’t until he did a pair project that he realized he was “looking at the code” after writing it. He wasn’t sure what he was doing, but when asked, he said, “I’m checking.” He goes through the code he wrote line by line to see if something is wrong.

How about a syntax check? I answered, “What is a syntax check?” After I taught her how to do it, she asked, “Are you okay?”

I told him to check it out, but he didn’t understand what I discussed.

Only then did I realize that confirmation other than operation confirmation combined with tests was not a habit? Unit tests must be designed to have consistency, so they require somewhat complicated preparations, and if you are not a test-first practitioner, the start phase will be delayed.

How to improve

Register the processing to check the syntax in the editor and execute it as appropriate. Then, if necessary, make it work automatically on save. Since the editor was Vim, I put in a plugin like Quickrun or Syntastic and let it run accordingly.

Anywhere is fine. Create an environment where the class/function can be executed alone, and check the operation. After confirming some correct behavior, move it to a test file.

Make a habit of that flow. Instruct them to complete those phases before asking themselves, “Is this OK?”

Once you get used to it, creating a small CI environment using a debugger or watch would be a good idea, and having it run every time you save.

Psychological problems

You may think these environmental problems are a matter of knowledge and unrelated to psychological problems. Still, if you look closely, they are binary, such as “correct code” and “errors you don’t understand why.” The part that is doing how to catch the problem is glimpsed.

There is no only correct code. However, this seems to be a common way of thinking for people who use copy and paste a lot, and the programming cycle of searching for something that does not work even if you copy and paste is doing something wrong and not being able to copy and paste accurately. I felt that there was a background in the fact that it has become a habit.

Therefore, once the code is written, it looks like a list of symbols, and you have to look for any mistakes with your eyes. Since my writing also starts with copying and pasting, it is a list of symbols I don’t understand.

Checking while understanding line by line seems less efficient than copying and pasting.

Don’t read error message logs.

Error messages in programming languages ​​and error messages output by libraries are information humans write for humans to identify problem areas. But slow-growing programmers don’t read it. It is binarized and taken as information that there was a problem.

If it is an IDE, you can immediately jump to the relevant part of the module. If this is raw Vim or a log message output via a web browser, it becomes your job to understand and jump.

It doesn’t read. It doesn’t jump to the relevant part, so the time to display the error screen is extremely short. I thought he was testing my kinetic vision because I was doing a pair project, and the error screen disappeared so quickly, but he didn’t read it.

As a result, I am staring at what I wrote earlier. I’m going back and forth between method names to see if there’s a typo.

However, the message output was not the message from hitting a nonexistent method. If you don’t read the error message, the possibilities for where the bug might occur are endless. However, he said he thought something he had written was “wrong” and needed to be fixed.

How to improve

Read the error message together and check the meaning one by one.

And let them understand the correspondence between error messages and problems. It also creates a minimal snippet that causes it and makes assumptions about various cases.

Psychological problems

He says, “I can only see symbols.” Language and framework errors are challenging to make sense of without understanding the terminology and structure of the language and framework.

It’s not because the language is unfriendly or the framework is unfriendly. The error message doesn’t represent the “implementation problem itself.” So knowledge of the framework, the language, and tracking the implementation only then can you connect the problem to the error.

Unless you make it a habit, the error will remain a symbol until you can do it yourself.

I don’t know how to find the problem.

For example, suppose that when an error occurs, the problem is discovered for the first time in the corresponding part written in the error message.

If that happens, it also means that the code worked, at least that far. Also, if an error has occurred, what you have entered has likely had an effect, and that is what is happening.

For example, with printf debugging, you can get an overview of the problem by looking at what went into the module, how it changed, and what caused the error, and then walk up the call stack to Able to identify problem areas.

However, suppose you don’t know how to search. In that case, you start checking from where it is expected to work usually or blindly output information without knowing the order relationship of the call stack.

Sometimes, they “get stuck” without knowing where the problem is. Without a strategy to identify the problem, it’s straightforward to fall into the phenomenon of “getting stuck.”

How to improve

After a problem has arisen, ask them to share their strategy for identifying it with an “Okay, what should I do?” before taking action. Ask questions such as how to collect the necessary information and to what extent is expected, and make a strategy.

Also, what does this mean if you get one piece of information? Will strategy change? Making them conscious of such things will lead them to search with a firm will instead of blindly searching.

Psychological problems

The fact that a program error occurs should be one of the pieces of evidence that it is “close to completion.” This is because one piece of information that has not been conscious of until now becomes clear, the part where the wrong hypothesis was made is rejected, and a following explicit action to correct it is obtained.

More or less, however, programmers who aren’t good at searching for problems tend to “panic” over self-generated error messages. “I’m sure it should work,” but it doesn’t. I think it’s a terrible “wrong.”

One example is the phenomenon of “I don’t want to run a test that should fail.” The most significant value of a test is that it fails and provides information. It says “This will cause an error.”

Aside from errors in production, no one will be bothered if an error occurs in the development environment. Rather beneficial.

It would be beneficial to have them experience and understand this area.

Good habits

You can get good habits by overturning bad habits.

  • Take time to read and understand code often
  • always use wisdom to simplify the problem at hand.
  • Don’t be afraid to make mistakes; make a minimal case to understand important information
  • Develop a straightforward course of action for tracking issues

Here are a few other things I think are good habits:

  • Improving and automating tools
  • boy scout policy
  • learn multiple languages
  • learn systematic knowledge
  • Is that what you mean?

Improving and automating tools

Good habits are easier to establish with good tools. For example, whenever I write a new language, I look for code for matters that produce standard output and incorporate them.

If it is an IDE, it will naturally compensate for the necessary space. I don’t want to spend precious keystrokes adjusting my coding style.

Boy scout policy

Boy Scout policy is to pick up any trash you pass by. Based on this, the policy is to correct garbage and errors in the peripheral code. I can’t fix the code unless I read it carefully, but since it’s a necessary step anyway, I’ll fix warnings, etc., at that time.

Doing this will naturally lead to a better understanding and cleaner overall code.

Learn multiple languages

Even if you learn only one language, you will be able to understand the points that are difficult to understand by learning multiple languages. New concepts are often just borrowed from other languages, so they are quickly mastered.

Acquire systematic knowledge

I want newcomer programmers to know The history of humankind’s acquisition of object-oriented programming. The quality of programming changes by knowing the background, history, and occasional issues. come.

Suppose you try to pick and choose what is good about knowledge or do not organize your understanding of grammar and paradigms in your way. In that case, it will become tips instead of knowledge, and you will end up endlessly pursuing tips without applying them.

Lastly,

Since I believe competence is integral to habits, improving habits will improve competence. And there are psychological barriers to them, and as a result, it is often the case that habits do not improve, and even if habits improve, it is impossible to become a super engineer in a leap. It is not a sense of helplessness but whether or not you enjoy learning new things that most influence your results.