I can imagine data structures and algorithms and coding competitions, but I've always struggled with the concept of drills for improving skills as a software developer.
Would love to hear ideas from others.
I can imagine data structures and algorithms and coding competitions, but I've always struggled with the concept of drills for improving skills as a software developer.
Would love to hear ideas from others.
https://archive.computerhistory.org/resources/text/Knuth_Don...
He's famous as a programmer who got things right the first time. And that's been consistent over his career. A lot of what's in there is obsolete, but notice that even in 1960 he was doing something on paper like the literate programming that he developed later.
I'm skeptical that the scope of things you can get working at all by mindlessly banging on tests without thinking about the problem is very large, and when you add other aspects of the software development lifecycle, your prospects seem very slender indeed. If reading your code takes "ages", how are you going to figure out how to extend it next week when you need to change what it does? How are you going to debug it when it crashes once you put in production?
I have written compilers in a somewhat test-driven fashion, and I am especially skeptical that you can purely TDD a compiler. Certainly I've never seen it done. I'm far more skeptical that you could TDD a compiler written in assembly language that achieves the kind of performance this scenario implies. (But tests, especially regression tests, are extremely valuable for writing compilers.)
The particular compiler we're talking about here was one Knuth wrote during a summer-long road trip for US$5500 (roughly US$120 000 today). So the situation was actually considerably more extreme than you're imagining — not only did he not have punch cards when he wrote the compiler, he'd never seen the computer. So he had to spend a few months debugging it after he actually finished driving to the other side of the continent where the computer was.
https://github.com/kragen/knuth-interview-2006#27---writing-...
I have been working on my current codebase for almost a year now and still haven't seen half of it. There is no just read over it because its massive. Tests are the only thing that makes it manageable. When I want to change something I can find the part that needs to change but I have no idea what features I don't know about that depend on that feature doing something. Tests allow me to very quickly automatically scan the code base to show what things changed.
I agree that tests are very valuable for the reason you describe, as well as for other reasons. What codebase are you working on?
I improve my typing speed with http://www.speedcoder.net/
Every time I hear a concept I don't know I make a flashcard and quiz myself daily. I also have a collection of problems to keep myself challenged, some are interview questions and others are common patterns.
Here are public decks for Python: • General Python - https://ankiweb.net/shared/info/1394656023 • Coding challenges - https://ankiweb.net/shared/info/223286091
I used to do regex crosswords, which really helped me cement my reading ability of regexes and in term writing ability.
I think programming is closer to writing than playing piano. The types of exercises that writers do to get good are to rewrite, reread and rewrite.
The code gets better, but the business outcome remains unchanged so it may look like waste. But it’s not waste - the micro skills acquired in the exercise accumulate.
Herein lies the issues for many of us in the corporate world. Unless I am get the rewrite done in the current testing (assuming the feature I'm working on isn't already test complete), convincing the testers to re-test is basically impossible (to say nothing of the project/product managers).
1. Make the thing from a book, verbatim, change nothing
2. Synthesize a new recipe from 3-5 recipes, changing stuff at will, but within the range for each ingredient
3. if excellent: goto 2; else: goto 4
4. Continue to make this dish, using this recipe, from feel until the output consistency is always delish
Being good means being creative and then being able to consistently hit the required output quality.
“I fear not the man who has practiced 10,000 kicks once, but I fear the man who had practiced one kick 10,000 times.” -- Bruce Lee
I was also told that cooking from good ingredients is easy, the hard part is figuring out what to cook given the ingredients you have on a given day.
And so if I were to codify all the types of common idioms as if they were scales - which I haven't done - I would be able to drill those, but I suspect that there's a lot of them that are different between different domains of programming, and that's a major source of expertise.
Likewise my approach to naming has seen some iterative improvement, and it's definitely a thing I am training as I go. Names are like comments: you don't really want too many of them in your program, because they can obscure other information. Standardized variable names are great, and dense code is great when you can get it without sacrificing much readibility. I spent a little while evaluating what length of variable is sufficient to avoid collision and maintain readability while getting good density where needed:
1 letter - fine for local variables using detailed mathematics, where each variable is necessarily used in a dense, non-obvious way and it would be reasonable to have an explainer comment.
2 letters - hard to use well. As abbreviations they tend to collide too often to be recommended, and they are hard to recognize.
3 letters - a sweet spot for density and low collision rates, but still often unreadable.
4 letters - sufficient for most abbreviations and many full words.
5+ letters - at this point a majority of single words you would use will fit, and so you may as well consider this as "I am spelling out a whole word", with the next step up being multiple words and phrases, and at that point code density is the main tradeoff being made.
A common naming idiom I practice is labelling array-like values such as min/max bounds numerically, e.g. an axis-aligned box defined with x0, x1, y0, y1. For a while I used "result" as the variable for all returned values, after seeing this idiom in Pascal. Then I realized that I could use "ans" (answer) instead and get much denser code in a lot of instances. It's little things like that, which add up to a pleasant, lower-friction experience.