Are you a good programmer?
This question isn’t something anyone can answer with an explicit answer.
It’s something wide that includes physical and mental abilities.
Chractaristics for example:
- IQ
- Personality
- Experience
- Knowledge
- Social interactions
- Adaptation
A good analogy would be to an RPG game.
As you level up and learn you get skill points which you can invest in certain abilities.
Most RPG games also include a “role” - Healer, Tank, Damage dealer, etc…
In real life you also get a “role” or a “Specialty”.
But instead of dealing damage, you usually have a title:
- Automation Engineer
- Cyber Security Specialist
- Team Manager
- Project Manager
Because of the different variety of abilities I’ll rephrase the question to:
“Is this particular developer a good choice for my team or purpose”
This approach is more goal-oriented and less driven by absolute values.
First set your goals then achieve them.
Characteristics of a person
There are 2 types of characteristics “Static” and “Dynamic”.
- Static - Things a person can’t change like personality, IQ , experience, etc.. Experience — nobody can gain a year of experience overnight.
- Dynamic — Things that can change like knowledge, motivation, health, etc…
This determines the abilities of a person and yet even better — determines what abilities a person can change.
Particulary interesting are Motivation and knowledge.
- Motivation:
A book I recommend is Dan Arieli’s book “It’s worth it” (שווה לך).
I’m not a psychologist but I can definitely say motivation has a great impact on a person’s ability to code something.
When a person codes with no motivation they will produce less quality results. - Knowledge:
The more the merrier!
We can’t learn absolute everything but as we aquire more knowledge we get better and learn different tools to solve different problems.
This will speed up the process of developing a product.
If a developer is able to construct a generic and reuseable component in no-time — it will benefit the future of the product.
Five big traits
This model tries to generalize the personally of a person.
It’s widely used so I think it’s a good metric to start from.
For those who don’t know the five factors:
- Openness — Open or more closed for new ideas.
- Conscientiousness — Determines the organization and control abilities.
- Extraversion — Is a social party monster or a shy library student.
- Agreeableness — Are you willing to work with others, or crush them?
- Neuroticism — Emotional control. Neurotic people tend to be more negative in thoughts.
Measuring the five factors alone won’t help you to guess right persons ability to cope with tasks or to code.
However let’s discuss their values for programming.
Openness
People that are high in openness tend to be more creative and intellectual, they can grasp abstract ideas faster.
This is useful for architecture, design and problem-seeking.
Some development tasks deal with unknown details:
- Unfamiliar code or tools like legacy code.
- Unknown requirements.
Conscientiousness
Organized people are good to have in any company- they tend to be clean, organize their work, recognize their responsibilities and follow rules.
People that are in other side of this trait tend to be messier, follow less rules and more free in their will.
I don’t say it’s always good to follow rules however it can play well or bad depending - on your goal.
In a big organization and managment positions you’ll probablly want more conscientious people while in a research security position you want those who might break the rules - to get results faster.
Extraversion
People usually think of programmers as the classic “nerd” type of a person.
Usually a white male that sits in the basement all day.
From my experience most of the programmers I know are really cool people.
Today it’s actually more important to have “people skills” in development positions — because you work with people ALL THE TIME.
Other development positions don’t require as much work with people like small start-ups or sisyphean work like in security research.
Agreeableness
This trait isn’t related to any programming activity.
I’d say this trait is important for large companies where people tend to collide with one another.
A group of low agreeable people will tend to collide more and raise their voices.
While the agreeable people will sit more quietly — this can affect important design decisions.
So my advise is — if you are an agreeable person, raise your voice if you think a decision is bad.
Neuroticism
Even people with negative thoughts can help in a design process or software construction.
People that are more neurotic can think of more scenarios where things will break and fall,
where the user would use the feature in a “wrong way” or not as intended.
Sometimes it’s all about managing the risks.
Social animals
The era of geeks sitting in their basement coding stuff is partially over.
Some jobs will require more alone times with the bits and bytes.
Most development jobs will require human interaction as well! … oh these nasty humans.
I want to discuss further down the road about personal characteristics and mitigating some of the risks that come with these characteristics.
Ego & Competition
Workplaces should reduce competition between teams — or at least reduce unhealthy competition where people will likley to take turns on hating each other.
Combining the Ego part you get a nice soup of stress and anxiety.
It may get the job but in the long run it will suffocate developers and will burn them out.
Esentially good developers will set their ego aside and focus on their craft.
Healthy Competition
The industry is a competition and each company is also a competition — that’s the nature of people,
They try to best one another. Some people will cope more, and some won’t.
Either you are coping or not, try to maintain a single behavior — do not make things worse.
Good developers don’t fall into competing with their peers because they know their worth.
Eventually everyone has something to learn from one another.
“A true master is an enternal student”.
Dealing with Clients
I don’t mean UI interfaces — what I mean are people who make requirements up.
In a mid-big company the clients are replaced with salespeople and product managers.
The sales will tell the developers “We can’t sell the product without X”.
Product managers may know the need of the clients and design a feature that will suit them.
The developer need to know how to take these not-so-technical requirements and make them yes-so-technical.
It’s not just translating coffee into code but translating words into software.
Dealing with Managers
Most of managers in the field were developers, but good developers =/= good managers.
If someone is a good developer, it doesn’t mean they’ll handle managers well.
However, good managers can take advantage of good developers effectively giving them tasks that suits them.
If a manager isn’t utilizing their developers, they will never be as effective as they could be.
Therefore it’s crucial to see if a working environment is engaging enough to utilize good developers and minimizes the impact of bad ones!
Personal characteristics imply that different people will engage more with different problems.
This apsect of humanity is important however there are different abilities to test in regards to our main question.
“Is this particular developer a good choice for my team or purpose”
We’ll continue this discussion on a more technical level.
- What is intelligence.
- What technical skills are important.
- How can we make the developer a better programmer by inspecting the environment.
Intelligence — IQ
We’ll abstract the ideas over a theory called: Cattell–Horn–Carroll theory.
Some terminology:
- Fluid — Raw power, pretty much what you are born with.
- Crystallized — Learning from environment, experience.
- General — General intelligence or the
g factor
. - Broad — Crystalized, Fluid, Memory, Processing speed.
- Narrow — A specific form of an ability.
Broad abilities sorted by importance — top most is what I think are the most important.
- Comprehension-Knowledge (Gc):
Includes the breadth and depth of a person’s acquired knowledge,
the ability to communicate one’s knowledge,
and the ability to reason using previously learned experiences or procedures. - Fluid reasoning (Gf):
Includes the broad ability to reason, form concepts,
and solve problems using unfamiliar information or novel procedures. - Long-Term Storage and Retrieval (Glr):
Is the ability to store information and fluently retrieve it later in the process of thinking. - Visual Processing (Gv):
Is the ability to perceive, analyze, synthesize, and think with visual patterns,
including the ability to store and recall visual representations. - Quantitative knowledge (Gq):
Is the ability to comprehend quantitative concepts and relationships and to manipulate numerical symbols. - Reading & Writing Ability (Grw):
Includes basic reading and writing skills. - Processing Speed (Gs):
Is the ability to perform automatic cognitive tasks, particularly when measured under pressure to maintain focused attention. - Short-Term Memory (Gsm):
Is the ability to apprehend and hold information in immediate awareness and then use it within a few seconds. - Auditory Processing (Ga):
Is the ability to analyze, synthesize, and discriminate auditory stimuli,
including the ability to process and discriminate speech sounds that may be presented under distorted conditions. - Decision/Reaction Time/Speed (Gt):
Is considered part of the theory, but is not currently assessed by any major intellectual ability test.
Analysis
I want to emphasize 4 abilities:
Comprehension-Knowledge (Gc)
By far the most important ability for a developer, it’s basically the description of the brain.
The ability to connect new information to the old one you store and the depth of this information.
So if you read something about C++, new information should reinfornce old ideas, or change them to be better.
If you gather knowledge and your old knowledge is simply dissappearing, learning may not be so effective.
Fluid reasoning (Gf)
Programming is all about being logical.
This is because basically it’s a circuit — 0s and 1s all over the place just in form of text instead of numbers.
Using logic we need to solve human-related issues with new information or missing information.
Long-Term Storage and Retrieval (Glr)
Are you running an HDD? Upgrade to SSD!
Memory is cruical, but don’t pressure yourself into memorizing everything, just like einstein said:
“I never commmit to memory anthing that can easily be looked up in a book”.
This is so simple and elegant I love this.
Half of the stuff I know is actually written in OneNote pages,
And I can easily look it with Ctrl+E shortcut.
Why do I need to memorize all the details?
Don’t remember details, try to abstract them in a way you remember.
For example C++ hides many details about allocations,
just remember there’s a concept of memory and it should be handled.
When the time comes, the details can be retrieved and then you can solve the allocation problem more easily.
Visual Processing (Gv)
This is actually something I acquired while playing Baduk (Go).
It’s not a “must have” ability but it helps if you can visualize your classes and solutions and how it will look like.
In games like chess it’s simply called “read ahead”.
The first process in software development is the design document and gathering prerequisites,
if you can visualize them and seek them before the need arises — you have yourself a better design step towards implementation.
Experience
We must discuss experience if we are comparing development skills.
Just like characteristics of a person, experience also comes with Static and Dynamic experience.
- Static -
Usually the same repeated task that is fully automated in our brain.
Like configurating a server or seeking information. - Dynamic -
Variance in the job — dealing with different challanges.
It’s not enough to say that a senior programmer has “10 years of experience”.
What did they experience? The same tedious year 10 times? Or actually 10 meaningful years?
From my perspective it comes down to a individual personaly,
people that tend to be more open (Openness!) tend to have more “fullfiling” years rather than executing the same configuration tool for 10 years.
Managers need to understand how to engage their personal better.
Even if they have high opennes with great amount of learning ability it doesn’t mean they’ll achieve anything if they are kept low on doing repeated tasks.
If you are a developer and you are reading this — Start to practice in variaty of languages and tools.
Learn different operation systems, learen how the network works, learn how Hadoop works, try to mingle with GraphQL, You get the idea.
Knowledge seeking
“To know where you can find anything that in short is the largest part of learning”. — Anonymous
Seeking information is the first step of being good at anything,
and with the internet of 2021 you can find practically anything —
Medical books, gaming coaches, car mechanics guides, How to water plants, etc…
For developers it’s crucial to know where to find the right documentation, the right api, the right set of commands.
Or else you’ll be the guy that asks too many questions.
Knowing how to seek your knowledge is a crucial step for being an independent developer.
Hobby, passions and the Ikigai.
Hobbists tend to be more passionate about their craft.
Searching for new frameworks and learning new stuff is part of the passion.
It’s also ok not to be intersted in programming after work.
From my experience people that see their job as something meaningful, will enjoy it more and try to evolve in the field themselves.
The japanese has a a word for it — Ikigai.
Finding your ikigai in a technology field can be fulfiling and meaningful.
Software development skills
The nicest people or the smartest people aren’t always good developers.
We’ll get over important set of skills for software development and see how they contribute to being a good developer.
Some of these skills are acquired from experience.
Design
Software engineers or so called “Architects” are the titles for the design process of software programs.
I’ve mentioned the design process couple of times here so let’s dig into that one.
The design process is the documentation of construction blocks in software programers (For example “Classes”).
Alterantives and the whys — Why did the designer choose to go with solution X instead of Y.
It should also contain more details like — configuration, performance metrices, compromises, etc…
Better designs come with experience.
From my experience there is no ‘perfect” design— strive for a “Good quality” design.
If a compromise is done — the programmer should know why it’s a compromise and what are the risks.
I’ve had one manager that told me it’s all about “Risk managment” — He’s right. Some solutions are risky,
The programmer needs to mitigate and control the risks.
Thinking in abstractions
Nobody teaches that stuff — abstraction and pattern recognition.
Beginner devlopers tend to be more specific on details, like: “We have a list of melons that should be transfered in a cart”.
So they go and implement a Cart class and also a Melon class and everything works and they are happy.
A more experienced developer would say “Wait a second, we have transportation of goods here” so they go and implement a transportation layer — because who knows - it’s no longer 300 b.c and we might have a train and not a cart and melons aren’t the only fruit on this planet so they go and build better containers so it can hold apples or watermelons.
Thinking in abstractions doesn’t cost you more development time if you — from experience — know how to automatically think in that way.
In terms of thinking and time it costs the same, a more experienced developer just recognizes this much faster.
Patterns recognition
In programing it all ends up it 2 terms: input and output.
A more experienced developer would know this already, a beginner one would just start to graspt this idea.
Actually the one the I learned it from was Uncle Bob, I really like his lectures and I think he’s one of the biggest influencing speakers in software world.(At least for me)
When I say patterns I don’t mean “Design patterns” — it’s also true but what I mean is reoccouring concepts that you’ll end up seeing in almsot all systems.
Input & Output are 2 patterns that will always be there — in classes, in methods, in systems, in APIs, etc…
After that it’s just a simple question of: How fast one recognizes patterns.
A good characteristic for development and programming is pattern recognition, because humans are good at this — most of people have no trouble in recognizing reoccouring methods and concepts.
Recognizing characteristics of software
Software has different end goals.
Real-time software isn’t like BI software and healthcare systems aren’t like gaming software.
Different software characateristics:
- Functionality
- Performance
- Readability
- Maintainability
- Resilience
- Portability
- Useability
Writing a software program usually ends up in compromises.
High-Performance code tend to be less maintainble or less readable because of performance patterns - Complicated algorithms.
Configurable systems tend to be less maintainable for operation — what kind of configuration we need.
A good mind would think on these compromises to achieve the end goal.
Functionality
The end result should function how we desired it to function.
If a pancake robot makes omlettes instead it’s nice,
but we required pancakes and now we are sitting eating eggs instead.
Furthermore down the hole — hidden functionality always hits a software in cruical spots.
Usually it means “Technical functionality” like if we want to send a mail —
what kind of SMTP client we’ll use or what kind of template for the mail we need.
Other hidden functionalities are stuff that wasn’t discussed with the client or something that didn’t come up in the design process.
The programmer fills the details, the higher level of details the better end result.
Readability and maintainability
Refers to the ease of understanding the code and the ease of fixing or upgrading the code.
A code that is easier to understand, fix and upgrade is code that is more resilient in the future.
New people will have easier time to get into that code and start to maintain it if cruical bugs are needed to be fixed.
Performance
Efficiency is key, a good mind will try to keep things as-efficient-as-they-can-get.
Again — compromises.
I won’t be going into the all shabeng of “Early optimizations is the root of all evil”
because this quote is annoying and got out of hand.
It’s actually not the complete quote so if you mind — go read the whole quote.
Other characterisits
A certian goal will change your code for good or worse.
A good example is exception handling - to throw or not to throw? This is a tough question.
The programmer will have to decide on what kind of resillience the software should have.
Using Tools
Tools are important for development, there are many small tasks we need to perform that aren’t related to code, it may be: accessing the DB, using 3rd party tool to test integrations, visualizing data, searching files, sniffing the network, reading logs, etc…
We all know these “gurus” where they have literally tools for everything.
It’s not that hard to become a guru in that way because all you need to do is keep a list of handful tools.
Reorganize tools, search for tools, build the tools!
A good developer knows his way around tools.
Version control
I think everyone are using version control nowdays.
Because version controls are used with tools it’s the same as tooling — know your way around the appropriate tools.
Testing & Automation
Testing is a controversial subject, so what I’ll say is my opionn.
First of all testing is a necessary skill to have — how to design them and how to write them.
Automated tests are even better — they are a reliable proof of quality that can run again and again.
Regressions are more easy that way, and at the end the QA can veryify that the software is in good shape and quality for production.
Working with these skills in a complicated development process requires experience and knowledge.
Knowledge is the dynamic skill so a developer can be better by gaining more knowledge on the subject.
So…..
As we discussed there’s no clear answer for the question “Are you a good programmer”, therefore I rephrased it to:
“Is this particular developer a good choice for my team or purpose”.
This article should help you raise more questions to answer in certainty.
Personality
- Is the developer personality matches the team oritentation?
- Would they create more stress or less stress.
- Would they likely to take part in team tasks or do they work alone more.
- What experience they have working with people.
- How agreeable they would be in meetings.
- Would they put their ego aside.
- Would they co-op with stressful clients.
IQ
- What is their ability to learn new information.
- What kind of patterns they recognize from software.
- How is their math skills.
- Is their logical thinking correct.
- How is their memory.
Experience & Software skills
- Would they suit to my environment.
- Can I provide them the needed tools to make the job done.
- Can they learn new tools.
- Can they co-op with lack of tools.
- Can they develop their own tools.
- How can I motivate them to achieve their goals.
- How is their CI and Version control skills.
People and Software are complicated.
At the end it’s about producing high quality software.
Thank you for Reading!