What is the most effective thing you did to improve your programming skills?
stackoverflow.com
stackoverflow.com
1. Syntax errors on compile (it was C). 2. Test failures. 3. Time of the run. 4. Lines of code.
Then I used R to create graphs and reports that were generated periodically. About once an hour I'd go look at them and see what synax+failure levels were per line of code at that time. I'd then plot this as a run chart and start trying to find causes of my high defect indicators.
Eventually it got to where I found a bunch of the ways I wrote defective code and started to avoid them. I have a set of macros for C now that prevent it, and I use the patterns in my other coding.
It was pretty insane though. I don't recommend it for anyone, and definitely not on a project you have to do for a living. Well, maybe if it's a missile command system or medical device.
I made a thing that takes a screenshot every ten seconds while I work and another thing that sticks them in a window with a slider so I can look at them in sequence.
Just yesterday I noticed that I had been daydreaming a lot lately. So I made something that would go through the sequence of screenshots and compare each image with its previous one and count every instance where the two images were the same (or almost the same). That gave me a pretty good indicator of how much time I spent daydreaming. If the numbers are right, then when I'm working on something boring I spend as much as 40% of my time not actively typing or anything -- just thinking about random shit. I'm thinking I'll try mindfulness meditation for a while and see if that cuts down on the daydreaming at all. We'll see how it goes...
The main thing that caused defects was not handling default cases in logic. Things like not filling in the dangling else of an if-statement, not trying to return a value from a function no matter what, and not having a default: in a switch. By always trying to include at least a comment there, or an assert it forces you to think about the logic of the whole statement and prevents bugs galore. Combine that with unit tests and you've got a good solid start.
I don't recommend it because it's an insane amount of work above just writing code. I think it'd be something I'd force on high speed students in a kind of "Boot Camp" situation, but not on anyone else. In fact, I think most programmers couldn't handle having a giant bag of evidence staring them in the face telling them they suck. Also I think most programmers wouldn't get the stats behind the analysis and just keep screwing it up.
I play guitar when I have to think about stuff. I take one to work, and when I'm stuck I bust out my guitar, a pen, and a note pad. I then noodle and practice, and as ideas come into my head I write them down without filtering.
Basically, you need a hobby. :-)
It is good practice to compile C/C++ programs with high warning level, and fix all the warnings before shipping.
Biggest thing I couldn't get right was automatically connecting frequency of errors to particular lines or modules. I found that I made the same mistakes over and over, and I had to just spot them and jot down what not to do or think of a ninja way to avoid it. I also found that there was a strong correlation between syntax/test failures while writing code and how bad the code was.
What would have helped is if I could calculate the stats per function, line, or file and then have some pattern analysis spit out common grammatical structures that I do which are correlated with errors. It'd be something like:
function/while/if/return 24% chance of defect found in blah.c:func1 and blah.c:func2
Then it'd get closer to predicting defects and letting me go check the spots it recommends.
But, never got around to it since it became really insane after a year already without that level of analysis.
However, this wasn't about find a bug but preventing defects by using evidence to retrain my behavior. The approach is to assume nothing, then use simple graphs and data to look for places where you can change how you do stuff to improve your code. It's not hard, just really tedious.
Instead of thinking, "How do I want this program to work?" I had to think, "How do I want every program to work?"
Instead of organizing this data, I had to organize any data.
Instead of worrying about what my customer needed, I had to worry about what to put in my toolbox before I called on that customer.
Instead of handling the current outlying case, I had to learn to anticipate possible outlying cases.
Instead of worrying about instances of what we do, I had to worry about classes of instances of what we do.
Instead of benchmarking and optimizing performance, I had to understand the kinds of things that affected performance.
Instead of scaling, I had to design an architecture that would scale.
Instead of conducting analysis and design, I had to build an application to handle and apply system parameters.
Instead of covering bugs, glitches, and inefficiencies, I had to eliminate them before they compounded exponentially before my eyes.
Instead of having fun, I had to build a world within which I could always have fun.
What do you think about YAGNI?
http://bit.ly/cpbljR (YAGNI Wikipedia article -- apparently HN doesn't like apostrophes in urls.)
I gave no advice. I shared my experience. Take it or leave it.
What do you think about YAGNI?
Never gave it much thought before. But after reading your referral, let me rephrase the question: "How do you know what you're going to need?"
After servicing hundreds of customers, I built a framework that provided what over 90% of had already needed. I figured it was a pretty good bet most new customers would too. So far it's worked out great. The framework has easily replaced one or two other programmers.
But then again, that isn't even what the original question was about. OP asked the #1 thing that made me a better programmer. This was the #1 answer by far. I think everyone should write a framework, whether you need one or not. You'll never think the same way again.
[Citation Needed]
You should do this. You don't even need a publisher, you could approach your topic like Zed Shaw did with "Learn Python The Hard Way".
Or you could do a series of blog posts. You WILL get feedback and this will improve your skills.
I've made way more money from my "Slicehost vs Linode" article than I have from my portion of "Tcl and the Tk Toolkit, 2nd edition", even though the latter required a ton of hard work.
I started in high school writing homework helpers in Java and C++, and writing graphing calculator scripts to make fun patterns. Then I worked with other programmers, and started structuring my code to make it understandable to others. Then I started ACM programming competitions, and learned to rigorously solve problems. Then I found Python, and learned that finishing can be quick and easy. Then I got an internship at a major corporation, and discovered I never want to be an enterprisey programmer. Then I got a GSoC gig and learned to collaborate remotely and make estimates. Then I got a real job and learned to work with code for months and years, instead of churning out small projects, and the importance of finishing early and often. Then I experimented with Lisp, and learned the importance of abstraction, community, and salesmanship. Then I played around with Tornado and started learning about the web. Recently, I got a better job and started learning the importance of testing, the importance of listening to users, and the value of a second set of eyes. Recently, I've started experimenting with the Android SDK, learning the power and limitations of major constraints.
I can't wait to see what the future holds.
We also had to implement a subset of the bash shell, a lynx clone, a GNU make clone, a Lisp interpreter and a Lisp-to-C translator.
Having to implement many of the tools I've come to use on a daily basis was a transformative experience for me, and a great way to learn how to write efficient yet safe C code.
That experience inspired me to take the compilers class the next year, where I programmed in a functional language (Standard ML) for the first time. I was impressed with the expressive power and robustness of functional programming, and I've clung to it ever since.
These two experiences also set me on the path to becoming a professor. Now I teach and research compilers and programming languages for a living. I find hardly a day goes by where I don't learn something to improve my programming skills.
The first revision took me around 6 months to implement, and the second about 3 days. Worth every moment of futzing around and hacking and designing.
The language is getting rewritten (this time with an actual grammar!), and I'm finding it still has a mountain of useful things to teach me about programming. I can't recommend it enough. :)
I built recursive descent parser, and a lexer using the posix regex libary in 2 days first attempt and extra 14 days for semantic analysis and x86 code generation which operated by walking the ast. Most of those days were mostly learning x86 assembly. I can't understand 6 months, unless you did everything from scratch like the regex engine I.E Constructing NFA's, converting to DFA's etc etc.
As far as the 6 months, it was my first major, major project and required so much learning and research on just how to structure code that it took a long time to craft. It didn't help that the design was so complex that debugging it was a chore. :)
Hence the V2 rewrite that took a couple of days.
* become more sensitive to your daily pain points and
move to eradicate them
* read other people's code
* before sitting down to build anything, think:
"is there an easier way to solve it?
* learn about good architecture and engineering
practices, but don't worry about them until
a) you know what you're building
b) they're a problem.
* learn programming languages in different
programming paradigms.I tracked, over a one year period, every single defect that made it into production that I had to correct. I did this at the inspiration of a book on continuous improvement I read. I analyzed the underlying causes of the defects, organized them by category, made Pareto charts, and looked at my underlying procedures to see how I could avoid them.
What I learned surprised me, and changed the way I approached projects from then on. What I learned was that by far the number one problem I needed correct in order to avoid production defects and downtime had nothing to do with my code.
I discovered that the number one cause of avoidable defects in production had to do with the quality of my test data, differences between production environments and test environments, and discipline in how code gets promoted to production. And of course establishing a process for such things as promoting code-- a process which is formalized, followed, every time, and continuously improved as needed.
Learning this gave me a new respect and appreciation for the importance of a faithful and realistic staging environment that mirrors production as closely as possible. It's often impractical or expensive to various degrees to replicate or simulate a production environment faithfully for a variety of reasons. What I learned is that not all projects deserve the expense and trouble of that faithful reproduction of the production environment, running production loads in staging. But to whatever degree we don't do that, we take on more risk, and it's good to at least understand those risks.
Perhaps I'm talking more about project management, infrastructure, process and procedure than about pure "programming". But what I learned through this one year exercise was that often times when people think about wanting to get better at programming, improvements in some of those areas are really what's needed to get to the higher tiers of excellence.
Which book?
Disclaimer: the above comment may or may not be based on several moronic experiences the poster is too embarrassed to confess to over his 20-ish years in the 'biz'. Maybe.
EDIT: I have a comp-sci degree; it taught me very little about 'programming'.
Not only does this help find bugs, it will force you to write code that isn't embarrassing. You will end up communicating much more with colleagues; before, during, and after the code review process. I believe it will clean up, or at least address, almost every bad habit you have.
If you can't get this at work, try an open source project that has a similar review process.
It stops lazy check ins and it means at least 2 people know what code has gone in recently.
Also, my intention quickly became more than just a social networking app, and I really wanted to turn it into a framework for social apps. So that brought up all kinds of issues of MVC framework design and how to build an API and other large architectural issues.
Not to mention that a lot of the project I've had to do myself, with both very little precedence, and very little help (comparatively). Some of that was my fault, for not being better at documentation and project management, but I also learned that soliciting help for open source projects is a lot harder than The Cathedral and The Bazaar made it out to be.
It's easier now, that the groundwork has been set, and there are competing projects I can look at and learn from, but the first few years of flying blind was a hell of a crash course.
I currently work at a startup where I am the only developer. I'm also starting a company on the side where I am the only developer.
Does anyone have any advice on how I can supplement this? I'm currently looking into working on large open source projects, so I can work with other people, but I'm just not sure if that will work.
Every app must have at least 1 non-monetary gains for myself. Examples:
* When I build an app with Tornado, it's because I want to see how event driven server works and how to interact with epoll.
* When I build an app with Rails, it's because I want to experiment with things I probably won't do for professional rails work. E.g. using Rubinius or Erubis.
* One of the older app I killed was written in Zend framework because CakePHP was (a while back) too slow and I think modularity in PHP app is a good thing.
* The latest one is being written in Lua because I have heard so much awesomeness about its JIT.
* With every single app that stays running, I continually learn something new about Ubuntu administration and jQuery plugins.
Of course I killed my apps if they don't take off because VPS renting gets expensive fast.
(The game was Close Combat, if anyone was going to ask)
Learn a new language. In particular, learn one that requires thinking about programming in a different way. Coming from Basic, C, C# and PHP, learning Ruby was a real eye-opener and improved my coding.
Find a mentor. Watching someone code who is better than you at some (or all) aspect(s) is a very quick way to polish your skills. Especially if you can ask questions and have them suggest improvements.
In a different way, learning Lisp and Prolog, which basically widen your perspective.
Also, I have a question; most people say that they learn by reading good code, which I agree. Do you have any recommendation of a piece of code that you consider it has "something to teach"?
I read moneyball (http://en.wikipedia.org/wiki/Moneyball) - a book about using sabremetrics to create a winning baseball team and realized that everything I knew about being a great programmer and creating a great team was wrong.
The key takeaway I took from the book is that the things we think make a great baseball player (such as RBIs and HR) aren't what help win a game. There are better stats, such as on-base percentage.
In the world of software, I correlate between winning a baseball game with shipping software. And I suspect that what we traditionally recognize as strong individual performance isn't really what leads to shipping great software (same as having someone hit a lot of HRs on your team doesn't mean you'll win a lot of games.)
Right now, I suspect that (so-callled) soft skills around communication and time management are the fundamentals stats that are more important. So I've focused heavily on things like personal and team time management, and writing skills.
Pair program/code review to learn what you're doing wrong.
Teach it if you want to really know it. PG's idea of writing a book is great, but I've found the interactive nature of hands-on teaching really makes me grok something. Writing, for me, helps me organize my thoughts, but coding is something you never do "perfectly" -- the goal is to solve a problem for real people, not create the perfect mathematical construct -- so I'm much more interested in how different personality styles and moods approach problem-solving in a language more than I am the details of the language itself.
Each of these works at a different level: strategic, quality-control, and tactical. Depending on personality type, folks have a tendency to get hung up on one level or another -- as if learning all the syntax of a language or how to use the IDE is the same as mastery -- but for me I've found I need all of them in equal parts.
Otherwise, you may find yourself being stuck to certain languages (and functions!) which can be pretty bad. eg Using if then when a switch would be clearer and quicker. Or, applying indexes to every field in the hopes it'll make the database quicker. etc.
That said, I found the best way to learn a language is to do an (Extremely small!) side project for a certain area. eg eCommerce website? Pretend you only want to sell 4 items (2 per page) and attempt to make it pretty so you understand how designers design. And aim to understand WHY the code does what it does. (There are more ideas and projects out there)
If you're going to attempt a start up, I suggest learning frameworks and APIs. Both typically save lots of money and time until you become commercially viable to cost (by then, you should be profitable).
I learned programming on a machine (ZX Spectrum+) which performed syntax checking as I typed. On the other hand, run-time errors often led to crash, making me loose my programs (system had no hard-disk!). Without me realizing then, it taught me how to write bug-free programs (since penalty for bugs used to be so high). Yet, with PC-based code editors, my programs have a lot of syntax errors.
I realized this when I met someone who could write five thousand lines of code without compiling even once and yet with less than two syntax errors!! This person was trained by writing programs on paper, and penalty for even syntax errors was set too high.
My lesson has been to dislike test-driven development. I like to certify my programs as correct by looking at them. When bugs are found during testing, my brain ends up getting trained automatically not to repeat those bugs without requiring tests to discover those bugs.
Refactor.
It might be enough to get a hack done to get some functionality working but if you never revisit it you wont learn what you did wrong or what you could have done better. Refactoring your solutions trying to improve efficiency, or usability (of the code), the process of examining your previous work and discovering how it could be made better will greatly benefit your learning process. Some times you may realize right away after finishing a piece of code how you could have done it better. Other times, its not until months or years later when you've learned and experienced more that upon revisiting the code you realize how you could improve it.
It's one thing to learn about programming techniques and designs, but it's refactoring your old attempts with those new techniques and designs that leads to understanding and empowerment.
If you don't have accountability, you don't need to make progress. No one knows or cares that you didn't work on your software project if you don't tell them. But if you have people counting on you, you have to make weekly deadlines.
Accountability is the key to success. Especially one it is accompanied by a strong desire to gain acceptance and approval from the cool kids (e.g. the really good coders who you are working with).
- Work with the smartest people you can.
- Strive for beautiful code.
- Keep simplifying.
Even any tutorials online or in a user group - it's never done. It's always talked about. I come from a engineering background so I really wanted to programming the "right" way. But here is so little code that includes testing that I can use to "tutor" myself. Even opensource.
I find this very odd.
Source code control, deployment and testing are all baked into the tutorial from the very first section where coding is started. It's also available in print form.
Speaking of books, Real World Haskell covers testing pretty early on; granted, being Haskell, whether or not it qualifies as "Real World" is still a little subjective at this point.
If you're looking for resources to tutor yourself, there are some TDD katas out there (I admittedly haven't tried it myself, though) - http://www.osherove.com/tdd-kata-1/
Program 16 hours a day. 7 days a week. Then sit and beam at my work.
PS don't program 16 hours a day. I had put ice packs later on my arms from the pain.
also get a super monitor, awesome keyboard, and a comfortable chair.