The most important software dev skills aren’t technical
spin.atomicobject.com
spin.atomicobject.com
But when there's a lot bigger population who all have a similar level of technical skill and that's not the limiter, I can agree these things are some of the important differentiators.
Of course if the technical skill is there then the most important skills will be nontechnical. :P
Is it really a case people have the notion developers min/max their professional skills like it was a video game where only the level of "programming skill" matters?
I doubt anyone who comes across these articles have so little life experience to actually believe the lazy stereotype "developer" = "anime watching shut-in with no life skills and can't function in society."
So what _other_ purpose does the article serve? Who is the audience, and what value do they get? (I have my ideas, I'm just asking rhetorically.)
Attention to Detail and Patience are key, often unsung, developer traits
Even the sloppiest coders who work with no attention to detail still compile their code with ease. I get the author's larger point about attention to detail but I don't think compilation is an effective example to illustrate that point.
And if it comes down to it, devs can still skip it if gets into a broken state for whatever reason.
Attention to detail in developer tooling can reduce the amount of details developers have to pay attention to.
In my experience, that is a state that would never end. It would work for a month, then break and would never get fixed again, and would fall into abyss of normalized deviance.
We have one managed by yarn where I work, and it's only broken on me once. I occasionally get asked for help (maybe 1/3years/person) when somebody gets a cryptic error (well, not that cryptic, but they ask me because it's git related) from it, and rerunning the hook installation task has always fixed it.
A strategy I have used is: - only lint the files that have changed - only apply lint rules that can be auto-fixed
This usually takes less than a second (short enough that you can't really tell the difference) and the developer doesn't have to do anything .
Yes. I work in a codebase that's 30GB checked out. It takes a long time to run our automated checks. That's why they happen on the server, when I make a pull request.
The upshot is the same: it doesn't go to master until checks pass. But who gives a shit about what I'm committing locally? I reserve the right to save my work even if things aren't compiling. You (my teammate) won't see it anyway, it's all locally on my machine. Why do you care?
GitHub/GitLab/BitBucket/etc all have this kind of system, it's not new or interesting.
git commit -m WIP
I hope you're rebasing that terrible commit message away before pushing this remotely.My commits locally are my business, and 100000% orthogonal to what YOU (my teammate) will see when I'm ready to make a PR. Because I rebase, I reword commits, and I squash things as necessary before I submit a pull request.
The horrible conflation of commits (what I do when I want to save my work) and pull/merge requests (what I do when I want to integrate my work into the repo that everyone sees) is the very reason why git was created to begin with. If you want centralized version control where "commit" means "everyone sees it and it has to pass checks", use SVN. Seriously, get away from my tools.
I'm all for validation that all commits must have some metadata/ticket numbers attached... at the time it is merged into master. Not on my local machine.
I probably did `git add -A && git commit -m WIP` at least 7 or 8 times today alone. But all my commits that made it into a PR were squashed, divided up logically, and renamed before they went in.
I'm trying to imagine a system where some automated thing prepends "TICKET#123 WIP" before every commit I make, locally, even if they're all getting thrown away before I squash/rebase/reword my commits. What's the point?
Omg don't use commit hooks for that, just make it as easy to use as possible for the developer (e.g. integration into the editor/IDE). For verifying such things CI is the way to go.
Simply never commit directly to your development branch, use feature branches and pull/merge requests.
1. Someone else (ideally the most experienced Person(s) available but even any second pair of eyes is better than nothing) can and should review the code 2. Hook it up to the CI, the CI should merge it into the target branch locally and do its thing, as long as a pull request fails the CI it will not be merged
Software (e.g. Gitlab) to implement such a workflow is freely available, you just have to set it up but that's worth the effort.
I still don't know why we haven't stolen the Photoshop layers paradigm and applied it to code
I should be able to toggle a shallow layer and deep layer all from a single 'file'
So the you'd be able to have architectural notes in the deep layer etc.
In many ways our tools are stuck in time.
The normal unit of editing work in original Forth was a 1024 byte "page" called a SCREEN. You would write your code in an editor that arranged it as 16 lines of 64 characters. At the touch of a key (usually), you could swap to the shadow screen which would have the documentation on it. By convention, shadow screen comments were placed on the same line as the code they were remarking on, so everything was usually co-located.
By abusing autorepeat, it was even possible to "flicker" the code and documentation to see both at once.
Something like CWEB or org-mode permits interleaving code with comments, but it's one dimensional and breaks your flow when editing.
I started playing with it a while back in terms of how you'd structure it and what I came up with was something like
foo.cs
foo.shallow
foo.deep
So that all existing tooling would work, foo.cs would just be regular old code and only if your editor supported layers would it care about .shallow and .deep, I didn't like that it would clutter up files.If I ever get the time I'd like to implement a rough prototype in intellij.
That's great and all, and I agree in principle, except time and time again I've witnessed people use the "my code is self-documenting" thing as an excuse not to describe anything they've written in plain English. Much of the time, it's pure arrogance of developers who think their shit doesn't stink.
I'm not expecting people to litter their code with comments explaining what every line is doing. On the other hand, a project that can't even run on a dev's machine without having to repeatedly ask someone questions is unacceptable, and core architecture and concepts should be summarized so that new developers won't eff up or rethink ideas that have already been thought out.
if case_that_im_not_going_to_bother_trying_to_test:
obj.method_which_doesnt_exist()This is 98% of why I push for continuous integration. I don't care about unit tests for their own sake, and I don't bother for my personal projects. I only want CI on a team so that when it turns red, there's an unbiased third-party building the code, and I can simply point to it and "the build is broken, please fix". Otherwise, I have to have the same conversation every week, and it always begins with "Oh, I don't think I caused that!"
I have a side job as an examiner for Danish CS students, and a noticible difference between first years and final project students is how they tolerate the frustration of having code not work. If you can’t sit through hours of not knowing why something just doesn’t work, you probably find a different field.
But I agree - you probably won't become a dev without having or learning some degree of patience.
They are content with the daily drudge of slow, manual tasks, whereas a truly good programmer would become frustrated and desire to improve things.
I think this is more about being diligent than being patient.
There are plenty (too many?) devs who will diligently try and figure out something but that have no patience when dealing with others.
Writing codes is completely different. I have to practice everything what others seem to do intuitively. I need checklists. I need to take notes. I need to review my task and codes several times. And still, I overlook the obvious and never spot the easiest implementation (even for trivial tasks like checking for empty Strings). All while it takes me a great deal of discipline to take care of the level of detail that is required.
If someone here has/had the same problem, I'd like to hear their solutions.
I mention these because they rely heavily on object-oriented and/or imperative programming paradigms. With C and C++, I still struggle often with striking a good balance between "writing a short solution that works well" and "writing code which is a joy for others to read". The former often relies on my technical knowledge and produces code that can be obscure to other readers, the latter often requires MUCH more concentration and attention to detail when writing.
However, I have recently started experimenting with declarative and functional Programming. Coming from an imperative background has made "relearning" how to program quite difficult for me, but I've just started to see the "elegance" in higher level functional languages, such as OcaML and Haskell. Of course, functional languages are often MUCH better suited to different problems than OOP languages, but combining filters, reductions, maps and folds seems to activate the parts of my brain that are much more closely associated with the "classical logic" side of programming. I think you should check it out if you haven't already.
I started with database programming, so mostly declarative. That was a joy and I did't need much time to catch up with the senior developers. Afterwards, I switched my employer and started anew with Java. I was completely overwhelmed and struggle to this day. Last week, I learned a little bit about streams and how functional programming works in Java. To my surprise, that seemed quite easy to understand.
I don't really know why OOP seems so much harder for me to do.
I use c# everyday at work and for the most part love it, but there are certain problem domains (anything with significant multithreading) where forced OOP thinking just makes everything harder than it needs to be.
It's not a pattern I have ever really wrapped my head around fully, but perhaps there is some structure in functional programming that if I view it through that lens it will make much more sense?
Try out a Lisp, maybe, or even something real fun like Prolog. There's still details to be aware of, but they definitely have a different "flavor" that might be more palatable.
2) Practice and experience. I think for the most part intuition is simply the result of experience and practice.
3) Learning different programming paradigms. Something that has helped me more than anything else I think is learning programming languages that cover different paradigms. I’ve never coded anything useful in Haskell, but just the process of solving basic programming problems in Haskell, with its strong functional approach, helps me identify issues with the proceduaral/OOP code which I do write to solve useful problems. I think it allows me to approach each problem from multiple perspectives so even if I don’t have certain Haskell features available to me, it makes it easier to recognize that this may be an issue I need to address in my OOP code (for example, the Haskell compiler when pattern matching requires all possibilities to be addressed. Awareness of this fact means that anytime I’m writing conditionals checking the input I’m much more aware of the fact that I need to also handle the else condition, something that most non-functional programming languages don’t hsually require in their conditional constructs).
4) Related to #3m opting for better solutions wherever possible. I always try and opt for expressions over statements. I try to avoid state change as much as possible. I try and minimize side effects in functions, and try to constrain them in specific areas of code, etc.
5) Formal CS study. I don’t have a CS background, but studying formal CS in my free time has helped a lot. Getting better at data structures, algorithms, formal verification, etc, has helped develop my intuitions even if I don’t sctually use those data structures and formal verification methods in practice.
Foremost: practice. If you can read and write essays at a college level you've been practicing the craft for (likely) years. Most educated people in the US start engaging with letterforms as soon as kindergarten (!), and no later than 1st grade if not preschool. Contrarily, we don't start so early with the rules of logic nor programming constructs. Most folks don't start programming until much later, and even those who are precocious in this regard usually don't begin using "real" languages (in other words, not stuff like lego robotics or scratch) until they are ~13 or so (of course, there are plenty of exceptions). As with most skills, practice is invaluable.
On a conceptual level, I found that making the jump from asking myself what does this code do to what does this code mean majorly beneficial. It may seem like a minuscule or pedantic semantic point, but it actually makes a world of difference. Just like essays, programs are expressing—they are saying something. If you shift from approaching programming from a goal oriented perspective to a communications perspective your code will probably improve immensely. I think this is the reason guys like Donald Knuth stress code readability and literate programming so heavily—at the end of the day, that's what's really important: communicating some idea—just like we do in plain old english. We simply have a broader audience (the latter part of which is very picky about what it understands). The notion of a proposition in logic doesn't do, it means. Programs are essentially a set of propositions which just so happen to have the side effect that they can make a device (a computer) do something when it interprets them. Just as linguistic commands ("go to the store") are "pure" and free of side effects in and of themselves—they only have effects under human interpretation.
On a somewhat related note, I find stepping away from programming languages and starting with pen and paper is great. I think people tend to let programming languages get in the way of the real nature of what it is they're doing, which is solving problems in a structured manner, using mathematics and logic (algorithms and data structures). You don't need a programming language to do this, it's only a vehicle to express your solution. Just as you'd often start writing a formal paper by exploring your ideas in an outline or notes, or a couple of first drafts in which you hash things out, you can start "programming" by sketching ideas for solutions and better comprehending the problem at hand. This will ultimately help you write better code. I think a lot of self-taught devs, such as myself, miss this part early on as our entry point into the discipline is often through the languages and tends to kind of remain at the level of the languages we like unless we dig deeper into the underlying formalisms driving them. Too often people just go along with their first-pass understanding of a problem and begin reaching for the libraries, language constructs, etc. that they think they need. Someone with formal training, contrarily, has professors that can help them recognize the concepts behind the languages and connect up and distinguish the notion of a language as a mode of expression and programmatic problem solving as a practice irrespective of the selected language.
OP brings up a lot of good points (who could argue with these), but overlooks my #1 fundamental: If you can't write good code, not much else matters.
I know lots of programmers who have mastered the technical skills but are weak at the other things, so no one would ever mistake them for "senior", no matter how good their code is.
But I know many more "I.T. people" who are good at the "soft stuff" (analysis, design, product ownership, people management, agile, etc.) but can't code. I don't want to sound snarky, but these people are a dime a dozen. They often have great attention to detail and patience, but would you really entrust them to build your software?
Learn how to build software first. Be able to do that well before adding the soft skills.
That's the most important software dev skill needed. And it is most definitely "technical".
Maybe this is influenced by geolocation or other factors, but IME actually competent "soft stuff" people are rarer than competent engineers.
Can't stress this enough and I frankly don't understand all these articles claiming otherwise, when even the most minimal reflection would clear things up in a jiffy:
Take a skilled trapeze artist who has great attention to detail (I hope) and is patient (I hope) but cannot code.
Alternatively take a brilliant software developer who is slightly sloppy and not very patient.
Which one do you want writing your software?
Of course, that's accepting that these are important skills/attributes. I don't actually agree they are. See
https://medium.com/@petecam/why-laziness-impatience-and-hubr...
I write average code but always seek to make improvements. I'm always trying to improve my knowledge on OOP and learn about different approaches to architecture but at my company I could write garbage code and nobody would care. Recently, I tried to make an update to a legacy software and the code was quite bad, methods that were 15K lines long. Terrible variable names, UI elements named button1, button2 etc. However, nobody cared because it worked, it served it's purpose for the last 12 years, and yes it needs a complete rewrite, but it would probably need that anyway after 12 years as there are some major business changes.
I think every programmer should try to make things and try to improve. However, over-engineering and writing too many unit tests can also be a waste of time.
Not sure why you think "great code" = "overengineering".
Great code is not overengineered, by definition.
Most software is written as a team nowadays. You may write great code, but how does it fit into what your entire is team is doing? Does your great code multiply the teams effectiveness?
You may have guessed it by now, but IMO for most cases communication is the first required skill, and then everything else. Obviously it's not the only required skill, but for me, communications importance cannot be understated.
To me, "solving the customer's problem" is part of the definition of great code. Not sure what definition of "great code" would not involve that.
And again, we are talking software. So you have an awesome communicator who cannot code (and can't delegate...). Versus a so-so communicator who can code. No contest.
We are all people before we are programmers, so I'd argue it makes sense to build people skills before programming skills :)
But I'm probably misinterpreting you.
To take a less extreme example, depending on the role I'd still rather hire someone who was occasionally impatient and didn't always write tests but knew how to code really well vs. a fresh grad who's always cheery and polishes the hell out of their work but takes a lot longer and produces meandering code.
It's quite possible to teach a conscientious person to write programs. I haven't figured out how to teach a person who writes programs to be conscientious.
I would strongly encourage placing less of your view of self worth outside of your “velocity”. That’s not the real world. Products will fail and it won’t be because you weren’t agile enough, it’ll be because the market is a jerk.
I actually haven’t heard much in the way of military analogies besides Palantir if I’m going to be honest, and I’m pretty sure they’re up there amongst the least desirable companies to work for in my eyes
Seeing as I'm currently sitting in my office at Adobe I would say yes. There are plenty of code jockeys like you churning out low-quality Java/Python/PHP/C/C#/JS/whatever. You, despite what you may think, are not special.
> Not your typical half-baked developer quickly churning low-quality code in JS that breaks down after 5 seconds of load you get headaches from as a QA.
Cute. I get headaches from the guys who think they're great. From the ones who think that not documenting what they do is time wasted because clearly what this does is obvious. I get headaches from the people who have NO IDEA how their code actually performs and if there's any kind of slowdown well just throw more money at the hardware.
I can practically hear you and the others like you cry out, "But it works on my machine!" Oh the headaches that has caused.
OK, I landed #1 spot on HackerNews with a product I mostly developed (under a different nick) some time ago. You know everything about me as well. It was also competitor of one of your products.
All I am saying is that these are assumptions/metrics with which VCs/owners run/structure their companies and what actually matters to them. I have experienced it dozen times. I have also experienced when I had to fix somebody's horrible code in production developed in high velocity/high stress/low quality mode that was bringing one famous tech company down (lawsuits etc.), and had to correct spots I'd never seen before in some of the most complicated areas of the product dealing with provably infeasible problems (distributed systems). I'd also experienced an environment in a relaxed top company (rated higher than either of FAANGs) where we discussed ad infinitum just individual names of functions, their parameters and if they perfectly capture their meaning and refactored them daily; I don't have to say that project wasn't having much of a velocity and its market share reflected that.
Most of the time they will be satisfied with an 80% solution.
A lot of people will just build stuff they find interesting/fun to build, but no one will care. What they will care about is whether it solves their problems, and they'll often go for a hacky, poorly done solution that does if need be.
The absence of this causes havok: a task thought done will turn out not-done at the deadline and become an emergency. A feature not measured against all the requirements will fail in test or worse! in the field and cause customer angst and extra cost to everybody.
Can anyone else even read it?
What is the end goal here and does this accomplish the spirit as well as the technical goal?
What about related features that are likely going to end up related to this somehow?
That and so many more things to think of that can change your direction, but long term really pay off rather than "code does thing, good enough".
I say that having just read a bunch of code that only does one thing, could only do one thing, and now has to be reworked entirely because it can't do much else / be adapted.
My thing is... did they even try? There's a lot you can tell that is not the least bit portable or changeable. If it doesn't meet some requirement in the future, oh well that happens no way to be 100% sure. But at least some effort might leave a path open, even if not optimal.
Conscientiousness is one of the 'Big Five' personality traits[1], and it is the one most strongly correlated with success in any field.[2][3]
[1] https://en.wikipedia.org/wiki/Big_Five_personality_traits
[2] https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2747784/
[3] https://www.businessinsider.com/conscientiousness-predicts-s...
Some of them were great and some were not so friendly. -Respect for others - Being friendly - Give good energy to the people around you in the office - Learn how to work in a team
Those are the things that when a good developer has, he becomes a game-changing part in a startup
It took me years to understand this but without being able to work with your team you will not e able to create great software.
It's possible to create a product that's not technically beautiful but it meets a real need in society. Ultimately we create software to meet a need. Once we understand the need we can go back and refactor it. But if we can't communicate and get along with our team then the chances of creating a good product are low.
I dont care how good your program or app is. If you cant talk like a normal person, accept criticism, negotiate etc. You are going to suck. The best co-workers i have are able to combine both the CS tech knowledge with other skills like good estimation, honest and open communication, clear planning and execution etc.
You can just tell in my opinion. Start workign with someone on a project for an hour and you can tell if they are a nerd without focus who spends weeks doing useless shit, or someone who will seriously contribute to your team and help get shit done.
The title doesn't match the article's intent.