"So is there any essential skill needed to be a programmer? Different domains obviously have different requirements but ultimately is there some commonality to writing code regardless of domain?"
Peters answer to this _really_ resonated with me - his first two sentences were "You've got to be able to make progress and then improve on it. That's all you need to be able to do in life."
How would you answer this question?
Specifically:
- Never say "Got it" or "OK" when someone is explaining a problem or solution and you don't follow. It feels awkward to say "Sorry, I'm still not following. Do you mean that when..." five times in the same conversation but it is worth your time and embarrassment to come away with a correctly framed and well understood situation. Otherwise you will figure out what they meant after wasting hours/days/months solving the wrong thing.
- You'll be faced with situations where your colleagues/organization expect you to implement solutions you think are not the best. Understand that "the best way" for the team or business is not necessarily the same as "the best way" for you personally or "the best way" overall. You are likely missing some context about the choice. Be mindful of reputation risks, time costs and maintenance costs involved in changing the approach.
When you're asked to code something you don't agree with (including ethical issues) your options include: silently accept their approach, refuse to do their approach, propose an approach (with conversation or code) and gracefully accept the result, or find another job. Be aware that different organizations will react differently to those approaches. Under no circumstances should you fall into the trap of spending a week to convince the team to adopt a change that would save a week of costs.
But when someone said they could do something a particular way and the results suggest otherwise I find it completely frustrating.
You can either develop both options and pick the best, or you can use "best practices", which is non scientific. Authority and tradition make best practices.
Also "don't @ me" about basic logic like nested loops and bigO. That's not what I'm talking about here.
It’s really obvious during remote work: PowerPoint then silence, then a bunch of assignments handed out. If you ask any one of the audience, coder to coder, they all have the same confusions; some write a fancy class template like ‘ProblemSolverObjectDispatchFactory’, others just ignore.
If it's a product/business decision and you care about that aspect of your work, dig down and understand the context, otherwise, before long you're likely to grow numb to that aspect of your work.
People like to feel like an expert, and will usually be happy to explain.
It will make you better (knowledge transfer to unrelated problems), your code better (domain knowledge), and your relationships better (recognizing your colleagues as peers with different skills, not just not-your-skills).
As a front end developer your existence is ultimately defined by your grasp of very few tree models, namely the DOM but also the file system and various similar concepts when writing systems automation. It is common for developers to not grasp the concept of implicit relationships, which are a fundamental consideration of tree models.
This is basic stuff, the foundation that defines your career. And still many developers do not grasp it. They spend so much of their careers hiding from the core concepts of their jobs dependent upon abstractions to reframe the technology.
What may begin as embarrassment evolves into stubborn resolution masking extreme insecurity. Everybody can see when you are embarrassed, insecure, and when you fail to understand something. So many times people will try to redefine an important problem to appear less lost or hopeless. When other people are really listening they can see through it. It’s only a shallow self-deception.
It’s okay to not know something and need help. Pretending otherwise is poor character.
Asking questions is the way to understanding.
The absolute worst is when a colleague does this on your behalf.
Being able to clearly explain why your solution will solve a given problem better than the alternative and listen to your colleagues when their suggestion is better than yours, will save you an incredible amount of frustration. It is in my opinion the most important skill I have learned
- Asking why when debugging
Finding the code that's causing a bug is only the first step. The next is preventing a similar one happening again. By constantly asking "why was this choice made", you end up finding the actual weak points in both the code and your process. Whether it's because a hack some other place forced you to write another hack, that then failed or because there was a deadline so the commit was made at 3am, there is an important lesson to be had. If you combine that with good communication, you can talk to the team about changing things, so you avoid creating similar bugs in the future. (Pro-tip: 99% of bugs are there because there wasn't time to do things better)
I'd be happy to elaborate on that argument if you have any examples of one or more situations where you wouldn't consider communication important? :)
For a very narrow definition of 'better', maybe. I'd argue most bugs are there because the cost of a bug is less than the cost of developer time it's take to prevent such bugs. There are industries where the cost of a bug is very high, but mostly bugs are like unemploymency rates: it's almost never economically feasible to get them down to zero.
Better is a subjective word, so I think I could have made my point more clear by instead writing "99% of bugs are there because there wasn't allocated enough time to prevent them"
Do you agree more with that statement than the one I originally posted? :)
You make it seem more planned and reasoned out than it really is. I mean, you can make a meta-argument, that market evolution and pressures push things towards that optimal cost-benefit spot, but on the micro scale it often just happenstance.
Again, the meta-argument can be that even doing the cost-benefit analysis is not worth the cost, but it's quite handwavy.
What counts as "better" anyway? From the engineering perspective it's about efficiency, bug-freeness, elegance. From the company perspective, profits. From the manager perspective, looking good and getting promoted.
You can often game the system by rushing a subpar product out the door, downplaying and not even caring about the defects, wooing customers into buying in with clever sales tactics and marketing, then moving on before things start crumbling down. In some sense this was worth it in terms of your personal costs and benefits and all was done in the best possible way.
To be a good programmer, if I have to pick only one "skill" I would pick systemic thinking/understanding. This starts with the ability to learn and eventually understand how a system works. The next level is the ability to create a working model of that system in ones mind. Someone who can do that will be very successful at programming anything in any language on any platform given sufficient documentation.
I saw many beginners who treat a compiler like a black box and attempting hand fuzzing until it happened to match the well-formed syntax and behaviour they wanted, while they literally holding a paper text book or opening a browser tab for a tutorial which clearly explain how it works and what they should write in a plain natural and native language of theirs.
One time, I was told by a beginner who copied an example code from a text book that it doesn't work. I looked at it. It was a fizzbuzz code, less than 10 lines. And she typed it wrong. Not just an ordinary typo. She conjured up really strange ill-formed syntax she believe it works somehow. There is a parse error message but she ignored. I pointed out the place on display with a finger and she still didn't get it. I place a text book beside the display but it requires a considerable effort convincing her the cause of the error.
Other time, I was asked why for(;;) ; else ; doesn't work in JavaScript. I kept saying because there is no syntax like that in JavaScript. You have to accept it as is or create your own language.
Sometimes, I wonder some people read natural language text by simple keyword pattern matching. People like above example weren't dumb. Far from it. They are smarter in their field than me. Yet, they failed at this basic literacy level.
I was going to phrase it as "simultaneously seeing the forest and the trees."
The vast majority of my programming career has involved (1) taking a huge amount of information (specs, code), (2) building a mental model of it at 2+ levels of detail (high-level to fit a simplified holistic system in my mental swap space, and detail to have all the details about this problem at hand), (3) identifying the needle in the haystack, & (4) coming up with a simple solution.
As the parable goes [1], it's knowing which bolt to turn & how far.
I agree - so much of our time is spent coming up with working models of systems
I wonder how many people have this ability, especially when reading about organizations like the one that went to Appalachia to teach people in depressed areas to program.
There's a particular micro-expression I sometimes notice with people who are working on a software problem. I notice it when something goes wrong unexpectedly.
People who aren't particularly talented at SW development, for a brief instant, give a facial expression of disgust when something crashes or behaves incorrectly. People who are awesome at development, instead, have a look of amusement like they're actually looking forward to see what happened. These facial "micro-expressions" are really fast and subtle, you really have pay attention and it doesn't always work but I've seen it enough times to believe it shows something.
I think this goes back to the impulse to "improve" things that Norvig mentions. You really have to enjoy the act of programming, to be willing to improve on it. It's a kind of feedback loop. Just MHO.
I find failures interesting too, but I'm not feeling happy when I expect the reason will be because the tooling I'm using hides information behind insufficient logging or the answer I seek is probably on a system I don't have permission to access.
1. All kinds of things that you never considered go wrong all the time. This trains you to consider what could possibly go wrong in the long term deeper and ever deeper. I find this carries over into non-coding activities.
2. You are continuously faced with problems that seem completely unsolvable. And, you keep solving them day in and day out for decades. This trains you to be (perhaps rationally) optimistic about what can be done. Because every problem starts out devoid of clues and devoid of clear ways to get clues. No idea what's happening or even where to look. But, it always turns out to be something! It's never evil magic. You might be left with the mystery of "How did this ever work?" But, you solved it. You committed the 3-line patch that took 3 days to write. And, you'll move on to the next unsolvable problem right after lunch.
But, I don't think this is the main skill in programming. Good programming is the iterative application of concision and honesty, tempered by the ability to interrupt overfocus so as to find the right balance between perfection and getting something done.
Sincere interest is.
To be a good programmer: very much depends on your area of expertise. Most of them need good communication skills, some machine-level understanding, some math or algorithm skills, some require high velocity / long hours... It really is a very diverse field.
But like for most jobs, frustration tolerance gets you surprisingly far.
At that moment, I had almost zero of the specific bits of knowledge required to make it work. I only used Linux sporadically. I never programmed in Linux. I actively avoided C for the last 40 years. Yet, I dug in.
Last night I got it compiled enough that it now starts up, and then hangs. This is a vast improvement from 2 days ago. I now have WSL installed, with gcc, automake, and all manner of stuff required to make it go. I still use Notepad++ and windows to edit the source (as the /home/mike folder is visible as a network share) I've even got git/github going.
I know I'll get it up and running in short order. Then I'll start banging away at it until it matches my ideas of how it should work. My goal is to produce a Forth-ish compiler that doesn't get people intrigued but then run out of steam.
STOIC checks all the boxes, it's Imperative, Structured, Object Oriented, Functional, Concatenative and HomoIconic.
And right now.... it doesn't even boot... but it will! That's programming!
People tend to identify themselves with technology they mastered and miss out on all the improvements that happen. This works for a few decades if they're lucky, but someday they're old and wonder why nobody values their skills in an obsolete technology.
We can't all maintain Cobol code bases when we are 50.
I think it's also difficult in practice because it feels good to master things in general. It's a nice feeling to know that you know a system inside and out, so detaching from that is going to be hard no matter what especially if you've invested quite a bit of your life into it
In fact, a 50 year old is more likely to have caught the rise of desktop GUIs and of Linux than have spent a career doing COBOL.
It was a joke that targeted the argument: "You know that old tech is still in use? Look at all the COBOL used in industry XYZ."
What I've found works better for me is identifying when things are barely starting to get ugly and calm myself. I tell myself that this suffering is temporary and remind myself I've been able to solve pretty much any problem I've faced.
I think this confidence is really important and part of it seems to come from having solved lots of problems in the past / working through frustrating periods. That's why "write lots of programs" is still my favorite piece of advice because it's a lot like "show up to the gym" if you want to get stronger.
Growing Google-fu is like getting good at smelling bad code, it takes experience, which you get via frustration and the application of gumption.
If you're not making headway, step back, sleep on it, and try another approach. Giving up will guarantee you fail. You haven't failed until you give up.
Also related, fail fast; do the minimum amount of work to create a proof-of-concept, to see if you're on the right track or not. Don't build the whole UI until the algorithm is working, don't focus on the wrong things, focus on the most important thing first.
And finally, know when to ask for help. There is no shame in it. It's better to ask for help than waste time.
Just. Never. Give. Up.
I think it's a really underrated / underinvested skill in the industry (from my experience) with a lot of complexity. For example, there's so many levels of listening. It's one thing to understand what someone is saying but yet another to pick up on meta messages (facial expression / body language) that signal true thoughts / feelings.
I whould say “understanding” part of communication crucial for programmer.
But always together with “converting what is understood in formalized logic”
A curious thing that happens every time I write code is that some unexpected error occurs. Sometimes it's trivial stuff, other times it's deep structure. Either way, you have to be bothered to make changes and test them. Sometimes this tree gets very very deep. See an error, Google it, find an example that mentions a new keyword, explore that cave for a day, return to previous branch, etc.
Something about this is related to addiction, I think I'm somehow fortunate to be addicted to something useful rather than just some molecule.
To me, writing solid code is like combat.
Debugging can be like picking threads out of a tangle of yarn most of the time. Often when you have the most riding on the line.
Stress management/Self-management skills are critical (should be in the top 3) and often overlooked.
I draw on whiteboards, in moleskins, on printer paper, on the back of resumes... anywhere and everywhere. I do this because I need to convey complex ideas to important teams who are NOT programmers: Product, Marketing, People Ops, and the C-suite.
Helping people understand my ideas through illustration creates buy-in from them and trust in me. You can be a great programmer, but if people don't know and don't trust in what you're doing you'll never be given the space to execute.
I'm not suggesting every programmer who works for the likes of Facebook, Exxon, and Comcast quit their jobs. (though, if they did, wouldn't that turn some influential heads in the right direction?) Simply push back when asked to work on something that you feel might cause harm.
And 3) the ability to think something through patiently, thinking of what should happen, and what could go wrong, and being willing to develop the skills to make a ~"plan" (i.e., a program) that will do it properly.
You waste more time defending something that will always need updates and fixes than you do getting things done when you lack humility. It is something I learned early on and I hope more developers learn it.
I will take a 'good enough' dev with a wonderful personality over an above and beyond developer with the most toxic personality any day of the week, unless I'm under an extremely tight deadline. A toxic developer can poison a whole team and ruin their productivity.
I think that good programmers also have a better than average short-term working memory space, so they can keep relatively complex structures in their head.
The worst feeling for me in programming is not knowing 'where' I am in the code, when everything just feels like some sort of mental mush and you just stare at code confused because it's clogged your head up.
It's really good to be able to really focus, rearranging things in your head, imagining how something might look before it's done and so on.
The essential skill to look for is the ability to imagine some system working differently from how it works right now. A good engineer should be able to imagine several novel, alternative states and compare them, thinking of various consequences and trade-offs.
I think a big part of _keeping_ that drive if you have it (or cultivating that drive if you don't) requires a sort of being able to experience delight / happiness from learning new things. Even the little things.
Like today, I learned a tiny shortcut in writing rails routes. Not a huge game changer obviously, but little things like that make me smile!
Second would be the ability to write a one-page summary of problem and proposed solution.
Good logical reasoning, and spatial thinking/skills, ability to build up complex systems from smaller ones, and ability to understand/debug how complex systems work, and no 'magical thinking', but ability to analyze things logically.
I am seeing here a bunch of answers that mention 'communication', 'write docs', etc... etc but those are essential skills for any employee in a large company, no matter what the discipline is.
They are not core engineering skills per se (though they are necessary to perform in a large company). If you can't code, or don't understand concepts your communication skills will not help you that much. Maybe become a PM, or some kind of manager, but not an engineer.
P.s I know communication is not core, as i have worked with many 'brilliant' engineers that they had poor communication skills due to be foreigners, or just personality quirks. While that will hamper their ability to get promoted to managers, or architects, they all were respected and did well as engineers.
Although high general intelligence is common among hackers, it is not the sine qua non one might expect. Another trait is probably even more important: the ability to mentally absorb, retain, and reference large amounts of ‘meaningless’ detail, trusting to later experience to give it context and meaning. A person of merely average analytical intelligence who has this trait can become an effective hacker, but a creative genius who lacks it will swiftly find himself outdistanced by people who routinely upload the contents of thick reference manuals into their brains.
"Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis."
Well-engineered programs cover all the cases: they handle what they must handle, and have an answer for the rest which is better than "oh shoot, didn't think of that".
The main programmer skill is remembering to ask yourself, "under what conditions won't this work?" or "what inputs or situations break this?" and being able to come up with excellent answers.
Also, asking this question: "though this appears to work, where are all the requirements (language, library, platform, ...) coming from which make it work, and are any missing?"
That's not all you need, obviously. No one thing is the magic bullet which will make you a better programmer. But the worst programmers I've worked with only write code which works on their machine, for their specific use-case.
2. Prioritization - Learn to prioritize and sometimes to say "NO" to people.
3. Delegation - One cannot do everything by oneself. Learn to delegate and get help from others.
4. Whenever you do some task, always question why am I doing this, why this needs to be done in a certain manner and learn all the background(domain specific) knowledge related to the task.
5. Learn how to debug - I cannot stress enough how important this is. Most of the time you would spend maintaining, coding, and changing, legacy/existing code written by someone else. If you do not know how to debug and follow the trail like Enola Holmes, you'd always have to depend on the help of others which is very inconvenient for you as well as for others.
Apart from that as mentioned in the other answers it's always good to be a smart cookie, but it's not essential.
Git and version control, learn them as in depth as you have time for. Every decent dev environment has these and the amount of people lacking this basic knowledge is staggering.
Bash/Linux or powershell/windows same thing. You can get an amazing amount of things done with shell scripting in your OS. Unless you have an insane amount of time I would pick one and learn in depth. These are rich systems.
A dynamic programming language in depth. There are so many concepts that will transfer between languages that if you know one in depth, you'll be able to pick another one up pretty fast as it's just semantics at that point.
SQL, this is an essential part of dev life and you will understand ORMs and data management better.
The personal skills:
Communication obviously. This is such a vague term and I think is abused as people just say 'lERn to CoMmUNicate' with no actionable advice. Things like politeness, small talk, respect for other's etc.
At the same time know when to be honest. I've seen the best communicators tell management exactly what management wants to hear over and over and projects kept being behind or over budget because there was a dysfunctional connection between the manager and the engineer who kept B.S.ing them with what they wanted to hear and the nitwit manager eating it up and for some reason never learning.
Systems reasoning, learn to understand the system from the line of code up through the stacks to the whole. Sounds cliche and it is but it will make you a better programmer.
Debugging. This will be most of your life. The more you understand the system, the better you are at it.
Managing upwards. Keep your manager happy and communicate your work to them.
What does that all boil down to? Probably curiosity, practically speaking. If you're genuinely interested in programming, and it's not just about money, status or proving some point, you'll be drawn to learn different things and have different discussions, over the whole course of your career, that will make you a good programmer, rather than just a passible coder.
A caveat: Just as being interested in and liking to play a sport won't get you to play at the top levels without talent as well, there are lots of programmer's jobs that will be out of reach, but others WILL be in reach.
To be an engineer one must love to learn, learn fast and be able to learn on his own. It's not a job where you can expect to get training, it's a profession where you must be able to do some of the growing by yourself. It's a constant stream of new tech and new business domain knowledge. Here reading skills are absolutely required: a lot of questions can simply be answered by the relevant man page or by finding a reliable source for whatever knowledge is required for the task. You'll effectively have to become a domain expert several times in a career.
Systematic thinking and pattern recognition are essential skills to have. Our industry creates buzzwords every month and new fads in programming languages and frameworks but most core concepts remain unchanged since their inception.
Logic is absolutely required, and the ability to use the scientific method. This is crucial when debugging where you'll have to observe a problem, collect data on state, formulate an hypothesis on what caused the invalid state and verify your hypothesis. There's no "big picture" here, and every detail matters when doing this so in practice an engineers will often have to be able to keep the whole state of the system in his mind and step through it.
Communication skills are great to have; they effectively allow you to delegate and help colleagues onboard to whatever you are working on faster. From an outside point of view it's effectively super-powers, and if you want to play the politics game, allows you to get the best engineers to want to work with you.
I spend a lot of time reading the writing of other programmers. I've read 4 page documents that are a slog and 20 page documents that are a joy. Your writing, in a lot of cases, will be people's first impression of you, NOT your code.
1) Literacy. You have to know how to read (and ideally write in) your native language at a relatively high level. So much of our craft's knowledge is written down, in technical if not arcane terms, that in order to learn you really have to read.
2) The ability to reason about causes and effects, that is, to envision in your head what the computer will do when it evaluates a statement in your program. Also, the ability to back-reason which statements will produce a desired effect. You need to be able to predict what will happen before you write the code and test it out after the code is written. You'd be surprised how few people have this ability developed and how hard programming is for the general population as a consequence.
3) The ability to be humble and stay focused. Your program will take much longer to write than you think it will, and there will be more bugs. You have to have the diligence and passion to see it through.
If you can do that, the rest of the techniques can be learned with time and effort.
When making changes to an existing system (whether its adding new functionality, extending existing functionality, or refactoring the code while maintaining existing functionality), try to understand the intent behind the current structure of the code and why certain design choices were made.
Once you understand that, you can add new features/extend existing features using the same design OR refactor the code with a new design without impacting existing functionality (assuming you don't have universal test coverage... which frankly will be the case a lot of the time).
Another tactic I use is verbalizing my design choices before/during the implementation of a feature/product. When programming, a lot of developers create a mental structure/map of the code base and what changes they are implementing. They know the changes they are making in their mind and know how to execute them. However, if they were to explain what they were doing to another developer (for collaboration, handoff, etc) or to business/product (ie. in order to explain estimations), they freeze up. Verbalizing your design choice will strengthen your technical communication skills.
Those 2 things aren't necessarily skills, but they are tactics that can be used to be a better programmer.
Better: I try to build things that are sturdier, more beautiful, and solves the problem better.
Faster: Each time I build something, it has to be done faster. Code is faster to read, modify, replicate. Code functions more predictably and is quicker to debug.
Cheaper: I'll keep charging more, but it will cost less. A fresh graduate might do the same for $2000/month, 3 months. I try to get it done in $9000/month, 10 days. Part of this is not spending too much time on something that might be scrapped later, knowing when to plan ahead and when not to.
The essential skills are not really math or writing. Some of it is raw technical ability - know when and how to use reactive programming, declarative, imperative, and so on. Sometimes it's leadership, speaking up when you're stuck or something looks pointless. Sometimes it's just knowing how to learn and unlearn, and how to filter out the golden bits of knowledge from the sea of useless, self-promoting articles and books out there. And it seems trivial, but one of the skills that lets you do all three is knowing how to type 20 WPMs faster and use keyboard shortcuts.
This is really really really hard to do, since we are mostly lazy beings who rather click 50 arrow up key to find the one important command than remembering it or just dont mind to repeat a mundane process without finding a shortcut to do it faster. Programmers who I met that manage to finish a task in 10 minutes instead of 1 day usually have this trait. But I guess this applies to other jobs as well ¯\_(ツ)_/¯
Btw, I used to work as a part timer at my university department. One day one of the staff ask me to reformat about 90 Excels document to her desire format, she spend 10 minutes showing me how to type them out one by one. After this, I went to setup Python environment in that computer and google how to read excel docs. In a few hours I have finish the work that what would took me more than half a day to finish.
The best programmers have an eye for detail that can see below the surface of a system. When someone says "we need feature X because Y", they take a Socratic stance and ask "Why do they believe X will solve Y? Why is there a Y? Is there also a Z or a W to consider?" These aren't necessarily coding questions, they're engineering and process questions. Anyone with some familiarity with a system and the tools can add feature X, but the best developers will think about the precursors and implications of X first in hopes of improving the system as a whole.
To be a programmer you need the direct hard skills of coding literacy, analytical and logical thinking, combined with enough grit and creativity to see a problem through to completion. If you have that, you'll be a decent programmer, but you may not be a good engineer.
Engineering requires the maturity of thought to consider your actions and your solution over time. It requires more wholistic thinking and not just from the tech architecture point of view. Human soft skills tend to be more important over these time scales: communication, empathy, humility, courage. It's these skills that sustain success.
[1] https://www.oreilly.com/library/view/software-engineering-at...
Do not accept "magical" behaviour.
I came across quite some projects which had Cypress E2E tests which were, according to the developers, "unstable".
So what is the magic part which makes it fail? There is no such thing as an instable test as such in a test environment, in this case it was a broken test with unmocked data which occasionally threw errors, depending on the OS and speed of the machine it was running on.
In another scenario the was a random number involved, which randomly chose a picture in the test development and depending wether it needed cropping or not, an additional popup would open.
I was told: "well, sometimes it works, sometimes it doesn't". Nobody actually investigated further, tests were excluded instead. Noone ever looked at the artifacts/screenshots/logs.
Always investigate, there is a reason for every "magical" behaviour.
What resonates with me is the sheer persistence of these learners in the face of the rediculous complexity.
I learned basic at < 10 yo but there wasn’t much to it i the 80s on a home computer. No browsers. No closures. No NPM. No errors because “Yer on Windows”.
You have people doing freecodecamp pushing arch other along, many self taught getting complex apps working with React. Starting from no experience.
So yes keep on going when you hit a wall, struggle through it, and the next thing, and same shit for the job interviews.
Persistence and a love of learning are essential and it’s horrible working with coders that don’t have this trait.
Also:
* team work
* emotional intelligence
* testing and quality
* understanding the business impact
* humility - it’s a skill!
* estimation
* pushing back
* job interview skills
* career strategy (I suck at!)
* going wide and learning lots of things
* going deep in some things
* communication
* inquisitiveness
* getting things done / staving off perfectionism
* some ui/ux awareness
* cloud architecture basics or sys admin basics
* and that’s not all! Etc. etc.
All of which you’ll definitely learn on the job so no need to stress :-)
When my kids were little I thought I would teach them programming. The biggest problem I had was teaching them what a variable was. They finally did figure it out after a lot of work.
Abstraction is the same barrier between elementary school math and algebra. Some people never do learn algebra.
you need to be curious about why things in a certain way or why they don’t work, to take them apart, to continuously ask why
along with curiosity you need to learn. ALL THE TIME. you job learning is never done. there are fundamental things that will not change with time but a lot of things will and mastering anything will be a lot of work.
and last: growth. you need to tackle bigger and bigger problems and understand more and more in order to not get into a dead end career-wise. your goal is that by learning basic building blocks (programming languages, frameworks, tools) you get to work on or learn more advanced building blocks. the abstraction level you work on should go up
I'm an outside consultant and I'm often called to fix stuff that other outside consultants built. Pretty much 100% of the time, I am there because somebody was lacking in attention to detail. Whether it is a misplaced semicolon or a 100mbit interface in a virtual switch or some doodad doing a TCP handshake in the wrong order, I think over half of the 'edge cases' that make it to me are because somebody did not cross their Is and dot their Ts.
I think that good attention to detail is essential not just in programming or systems, but every technical profession.
For me, a good programmer realizes that "everything is code". Like, sometimes it's easy to think X problem is too hard for me or I don't have enough experience or this bug is unfixable but end of the day, it's all just code. You can change it however you want and if someone else did implemented something before, it's highly likely that you'll be able to do the same. Having a level of distance from the code one writes really helps.
Competence in engineering and architecture come from expanding the capabilities of your mind to simulate more complex programs and to think in abstractions.
I would say it comes down to a character attribute, and a simple skill. The attribute is curiosity - why does something do what it does, and the simple skill is how to google. That's it. I've seen the most traditionally under-qualified people become excellent, simply by always asking why, and trying to find a answer.
It depends on the problem domain. If you're writing low level code for a microcontroller that might require you to be able to do problemsolving on a whole other level than say writing CSS or arranging pre-built React components in a modern web application. In the same way styling those components might require a very different skillset in terms of taste, A/B testing etc.
In other words:
- Empathy
- Listening
- Communicating
- Collaborating
- Abstract thinking
That can be interpreted as reading someone else's code, but even more importantly: Just being able to understand plain English (or whatever human language).
I've seen so much code that used an API incorrectly, or misunderstood (or simply ignored) documentation. Being able to RTFM, imo, is essential. See also: Understanding what your boss wants and delivering it.
After the inception of stackexchange, the ability (or motivation) to read man pages seems to have have plummeted.
At many times during the process the formation isn’t expressed in code yet, so it’s up to the mind of the programmer to keep the pieces fitting together as intended until the code can be written and take a little bit of the lift from the programmers brain to expressed code.
If you're just trying to be a hobbyist and do stuff for fun then I'd say you need some things that aren't necessarily skills like curiosity, a love of challenging problems, and ability to easily retain information that you read.
- Selecting good names
- And thinking straight forward, being able to count from zero to one and two and so on.
And no, it is not just a joke, but my actual opinion, that understanding the underlying machinery, communicating well, and being to able to think on your own through complicated matters are the most valuable skills in programming.
[edited layout]
also, knowing how to say "no" professionally and firmly is an important and respected skill.
finally, being able to see the forest through the trees and value the business side of what you're doing is a key perspective. Everyone loves to trash talk Sales/Marketing/Management but those people turn your programming into your paycheck so a little understanding is deserved.
Being able to create mental metaphors of systems or problems, solve the metaphors and apply the solution to the original problem.
problem decomposition is maybe not the central skill, but the one that helped me most so far.
Work smart, not hard.
I think it also helps if you have a skill for quickly deducing what's wrong when there is an error.
So being able to troubleshoot an error or bug quickly is my favorite coding super power.
Being able to Google a solution or something close to your coding problem/challenge and being able to adapt it and make it your own is a huge plus as well.
If you think about it, software is driven by business requirements in most cases. But business requirements are open to interpretation. How do we know what people really want? This comes down to good communication.
2) Aptitude