A group blog from members of the VB team
I’ve always enjoyed writing. Putting pen to paper (or, these days, fingers to keyboard) is something that brings a lot of joy into my life, even more than music or any other hobby that I have. I’ve been writing stories since earlier than I can remember, have faithfully kept a daily diary for many years, and have published countless journals, conference papers, and other articles on this or that technology.
So, when I was in my early twenties, it seemed the most obvious thing to try start writing professionally. I wrote out a number of stories (mostly science fiction), which I sent in to various magazines. All of them were rejected. This was a source of frustration to me for quite some time, and as I personally found my stories to be engaging and eloquent (why not?), I couldn’t understand why these obvious “gems” were being overlooked.
I could have given up, and I was tempted to. But I instead decided to get into it from another angle; why not practice? There was this new thing called “USENET” which leveraged the still-nascent Internet, which was read by people with very similar backgrounds to mine. I started out by writing short parodies, figuring out what worked and what didn’t. (Some of my Star Trek and Black Adder parodies are still lurking out there on the ‘Net, much to my embarrassment. If you come across them, have mercy on me. J)
I got a lot of healthy feedback from friends and ‘Net acquaintances on these attempts. Gradually I came to realize that there was a lot of difference between having a good idea and describing it well. There’s a fine line between too much description and not enough description, and I tended to err on the side of “too much.” It’s a problem I still have to some degree even now – for the technical writing that makes up much of my authoring, it’s not a big deal, but it’s deadly for any writer who’s trying to keep the action moving. This was a good thing to learn, I’ve gone on to publish one piece of fiction, and I do plan (if I ever get enough time) to try my hand at fiction again – and in the meantime, I have learned many things that have helped me in the writing that I do daily.
So, what has this got to do with programming? Well, this is going to be a slightly odd column – not my usual coding example, but more getting into how we learn and improve our skills. It’s motivated by a comment from “jerry” (which you can find here), in which he asks:
“[…]I've been trying and trying, searching endlessly on the internet, but i can't find anything on the internet that really teaches me more. It's either easy stuff, or articles like these *gulp* that are way too far beyond me. And just experimenting takes forever, and usually doesn't show much results, because i don't know what to look for. How can i learn?”
This is a great question; one that I wanted to spend some time on, rather than just ad-lib a few reassuring sentences in a comments section. How exactly do we learn to be good programmers?
Before I get into “ways of learning,” there are some basics I should touch on first. There are a few talents that I believe all good programmers share, the benefits of which extend beyond programming. Three of these include:
· Pattern matching: A good programmer sees patterns in how work gets done. These patterns can be used to generate the spec for a program (i.e., tailoring usability to match a cultural meme), or to generate the basic architecture for their code (i.e., boilerplate). A truly great programmer, however, will intuitively know when to ignore these patterns and move forward to something new so as not get trapped in an obsolete way of doing things – this is referred to as “thinking outside of the box.”
· Efficiency: A good programmer is capable of reducing a complex problem to a simpler one. (Some skill at pattern matching is a prerequisite for this talent.) This talent is exposed through the crafting and reuse of good code. A truly great programmer will be reevaluating plans and code even after they are complete, and for as long as they are relevant, and have the desire to accept honest feedback on the work to make sure that it’s as efficient as possible.
· People skills: Really? In a programmer? Well, yes. Without this, you can’t accurately gauge what the customer needs, or communicate your ideas, or…well, do anything that involves people. There are people who can write good code and have good ideas but you’ll never know it. A great programmer can sell new ideas to their team because they know how to explain the ideas in such a way that people immediately understand them.
Given these talents, my opinion is that you should be in a good position to grow your skills as a programmer, no matter your current expertise is. (Not coincidentally, interviews at Microsoft are set up to gauge these three talents, as well as general know-how.) So now, let’s take a look at some learning opportunities.
Back in the early 80’s, there were a lot of magazines that one could purchase that had lengthy programs written in them, all ready for you to type into your C-64 or TRS-80. (I personally read Compute! magazine myself, being a C-64 user.) The programs were fully printed out due to necessity – 5.25” floppies disks were still a new thing then (many people, like me, were still using tape drives), and publishers didn’t bundle disks with magazines until later in the decade – too expensive!
The side-effect of this was that the user was essentially forced to *be* a programmer by virtue of typing in the program, unless they bought pre-packaged code (of which there wasn’t much). Anyone paying attention to what they were typing – if they had the talent – would be recognizing the patterns and thinking “Hmm, what if I changed this? How about if I do that instead?” In fact, I’d be willing to bet that that’s how 90% of programmers in my generation got their start – they began with someone else’s example (even if they didn’t understand it), and started tweaking the code, little by little (as well as coding around typos inadvertently introduced into the article). Gradually, they’d recognize patterns, and start applying them to their own code.
This sort of example-based learning is something that I still do today. When I became the lead of the VB Compiler Team back in 2003, I knew nothing about compilers beyond what I’d learned in college nearly 16 years prior, so I grabbed the compiler code, wrote a simple program, and stepped through the compiler line-by-line to learn what it was exactly that my new team owned. In more recent days, when I’m working on “hobby” (i.e., non-Microsoft) code, I’ll sometimes stop at open source sites, download the code, and do pretty much the same thing I always did – step through the code, tweak it, and see what happens so that I can learn the basics. (Edit and Continue makes this pretty simple to do.)
The epitome of example-based programming is to take code written in one programming language and porting it to a different language. You can learn a lot that way, especially if you’re currently weak in one of the languages. I’ve done this a lot in the past to get past the learning curve – for example, the very first code I posted in my VB blogs was a VB port I’d done in 2000 from some C++ code I’d written in 1998. It was the first full program I’d ever written in Visual Basic! I learned a lot about the differences between the languages, their strengths, and their weaknesses.
Oddly enough, these blog entries of mine are a sort of homage to the old Compute! magazine, with code interspersed with discussion – like other authors on this blog, I’m motivated to both present the code and talk about it as well, so that it becomes a good learning experience. Our own MSDN Code Gallery is good place to find code samples, and there are still magazines out there which publish code for you to try as well. And if you run across a programming concept that seems too hard – ask the author! You can’t expect the author to write your programs for you, but he or she will likely be very flattered to get questions from you and happy to clarify issues that might be too vague. At the very least, it gives the author something to write about for his or her next article!
Occasionally, you get the opportunity to build on someone else’s code, and that’s a great learning experience as well. A gentleman by the name of Ken Mattern has done this with the MIDI code sample app that I posted a few weeks ago (here and here). You can find his extensions to my code here. Basically, he’s taken my code and added a keyboard and other controls to the form, which makes it a lot easier to enter the notes (you can even hear the notes as you press them) and is a big improvement on the interface that I had created. He was gracious enough to point me towards his extension, and he and I have exchanged mail on ways that the keyboard code could be made even more efficient. Win-win!
Visual Basic in particular has always had a great community from which to learn, and one sure way to learn more about coding is to join a VB User Group. There are many of these around the globe, and you can search the ‘Net to see if there’s one in your area. I’ve visited with some of them, and I’ve always been really impressed with them – the members are really helpful to each other with respect to learning new concepts. You can also get involved with “group projects” at these meetings – collaboration is a sure means of getting feedback on your skills and learning new tricks, as I’ve discovered at Microsoft.
And sometimes, you just need to take lessons. For example, I’d gotten back into golf recently after an injury got me out of the game a few years back, but was doing really poorly. Despite helpful advice from friends who are good golfers, and despite watching them play, my game didn’t turn around until I got lessons from a pro (and boy, did that help!). The same thing works for programming – sometimes you just need to study with a master.
This doesn’t necessarily mean taking classes (although there is certainly something motivational about getting graded on your programming, having an instructor at hand, etc.). It can be as simple as buying a book at your local bookstore. There are literally hundreds of books which can teach you to be a better programmer, and buying 2-3 of them is definitely a good investment for anyone seeking to improve their programming skills. (My shelves at work regularly contain books on COM, .NET, international programming, security, and so on.) If you go this route, here are a few things to consider when shopping for a book:
- Does the book provide clear descriptive text for the code?
- If a true textbook, does it provide a solution for the problems it sets you to work on?
- Does it explore different aspects of coding – data, forms, web use, etc?
- What level of programmer is it aimed at?
Read through the first chapter at the bookstore before buying the book – that should give you a good idea of where the author is going.
Community colleges and night schools also often have inexpensive courses in programming. Sometimes these are tilted in a particular direction (web development, rich client apps, coding in C#, and so on). You want to make sure that the course is about programming applications instead of using applications, of course!
At this point, I’m going to throw it open to everyone else to comment. Have I missed some obvious learning mechanisms? What else could a person wanting to improve their programming skills do? I’m looking forward to hearing back from everyone on what’s worked for them!
‘Til next time,
P.S. I’ve uploaded yet another version of the VBScreenSaver code to fix a bug I found last weekend. It turned out that, in the unlikely event that the same random number is chosen twice in a row, the code was attempting to access the same picture before it released it, leading to a resource contention exception. I’ve fixed this by simply returning from DrawPicture() without doing anything if the random number is the same , keeping the current picture up until the next time event. It’s not a frequent enough occurrence to warrant anything more complicated than that, such as releasing the picture (which would cause a flicker) or generating new random numbers until we get a unique one.
Private Sub DrawPicture()
' Which picture? Get a new random number
Dim index As Integer = Me.m_Random.Next(m_fileCount)
If m_files(index) = m_currentFile Then
' We are already looking at this file and will get an exception
' if we try to open it before we close it.
' We could call for another random number, but why bother?
You can find the updated code at my Temple of VB site.
I'm not aware of any sites that are specifically oriented to small exercises -- there are a number of sites that walk you through code, but there's no gurantee that the exercises would be short! :-) In your case, I'd suggest getting a book instead -- they're more apt to have consistent exercises.
Nice article with some good points :)
Memories of randomly deleting lines from old RM BASIC programs to see what happened... :)
Thanks for the compliment. You know what always drove me crazy -- the programs in a number of the magazines used a different BASIC than the one on my C-64 ("What the heck is an LPRINT? Is that just PRINT?" :-)). Occasionally, I'd run across a programming vocabulary (such as a DO loop) that C-64 didn't support. That actually ended up being a good learning experience, though, as I had to rewrite the code to work around it. (Later, when I upgraded to the C-128, I could then do it in reverse, as it supported a lot more of the language elements that we take for granted these days.)
First time I ever programmed was on the ZX81 from a magazine listing. I was 10 maybe. Sat for hours typing in the 5 pages of code and was very happy when it came time to run it. Typed in the command and... 'syntax error'. Never again I thought! well turns out I thought wrong. Happy days.
How to learn is an 'in' subject for me at the moment because I was never taught how to learn but I do everyday.
There is an excellent book on the pragmatic bookshelf called 'Pragmatic Thinking & Learning to Refactor Your Wetware' which covers a lot of interesting topics related to better ways to learn. One of the learning approaches it recommends is learning through teaching.
Another skill a programmer needs in my opinion is spatial reasoning; the ability to visualise patterns, concepts and abstractions. It's an almost artistic quality. Good example are mathematicians ability to visualise what a formula actually means. Guess it's the ability to understand abstractions and to visualise how they fit into the big picture.
Great post and a huge hello to the VB Team.
Yeah, I'd definitely agree with the spatial reasoning. In my case, I sort of visualize the different modules of a program floating around -- how this one leads to that one, etc, how modules relate to each other, and so on. The first thing that I do when I'm code-reviewing in an area I'm not as familiar with is to get a pen and paper and draw what I think the architecture must be, based on the code that I'm reading. I find that makes it easier for me to grasp what the code is doing.
The downside is that I occasionally run into "official" representations that differ from mine just enough that they confuse me. It seems silly in retrospect, but I always had problems with the COM box drawings that you always used to see in technical books, because I kept interpreting the left side of a box as containing the method inputs and the right side as containing the method outputs (as opposed to all of them just being interfaces).
If you ever have the urge to blog sometime, and don't have an idea, here's one: a search engine! A program that searches items in a database.
Several years ago, I actually did create a mini-relational database and lookup service for one of the products we shipped (Setup & Deployment Projects). But the problem with doing this in Visual Basic (mine was written in C++ back then) nowadays is that, in many ways, it's *too* easy (or easy even that it makes for a very thin blog). Given LinQ & control databinding, combined with the various flavors of SQL, it's almost anticlimactic to come up with a quick search engine operating against a database -- a little bit of UI, a couple of lines of code, and voila! (Darn you, you VB team -- leave us something complicated to blog about! :-))
Hello, couple of things i'd like to say. First, I've found a way to learn coding easily: "For Dummies" books. I've read a few of them on other subjects, like hacking for dummies, and it turned out to be very informative and easy to understand. I expect to be out at the local Barnes & Noble soon picking up for dummies books on vb2008, sql, and xml :)
And another thing. I'm PRETTY sure you haven't already posted something like this yet. My visual basic idea is...an antivirus. Have any ideas? thanks
(Sorry for the late reply; I've been on vacation.) Yup, you haven't seen me write a post on antivirus coding, and you never will -- that is probably the only subject for which I would never consider a post. No offense; it's a good idea, but I am absolutely unqualified to write up such a thing. I know a bit about it, but just enough to be dangerous. :-) I shudder to think what would happen if someone were to rely on any antivirus code that I wrote up. It's better to learn from the experts in this case.
I didn't mean RELY on the code, just observed. Perhaps other people would take the idea and modify it, tweak it, make it better, and other people keep refining it until it's something that actually resembles an actual antivirus...? I'm just saying, it might be a good learning experience.
P.S. Just thought of this too...you say to learn from the experts...ok, who do you mean? Because i'd be happy to learn from anyone on the subject :)
"I didn't mean RELY on the code..."
No worries, I understood what you meant. Unfortunately, the assumption that I have to make is that my code could be used, line-for-line, by anyone reading this blog. It absolutely happens. That, in turn, incurs a certain amount of liability. I am not a security expert by any means. I know enough to write secure code and to review other people's code to make sure that it is secure with respect to our current understanding of the threats involved. But that's a far cry from writing an OS-level service to scan files (including protected system files) for viral infection and/or look for suspicious file access, potentially repairing files in a way that doesn't break them (a key feature of any antivirus software), and doing all of that without causing problems in the OS by temporarily locking files (which is not trivial -- one of the biggest headaches that antivirus programs have to deal with is resource contention).
Furthermore, to test or demonstrate such code (which I would be honor-bound to do if I was pushing it as a "how-to"), I'd have to deliberately infect a machine with some virus, which I am not allowed to do on my work machines, and which I won't ever do on my home machines. So, there it is...
Regarding training -- first, I'd start with learning about secure code. "Writing Secure Code" by Michael Howard and David LeBlanc is essential reading, and all of us here keep that book on our shelves. Once you have an understanding of where the failure points are in a system, you can better understand how to defend those points. It's not exactly related to viruses, but it's still good, raw knowledge that you will need to have.
I don't know of a good resource offhand for the specifics about antivirus software; oddly enough, I've never been as interested in it, and it's one of the few areas of coding that I tend to treat as "block box." (I'm required to use MSFT antivirus software on any machine that connects to the MSFT netowrk at work or home, so considering the various alternatives really isn't useful for me anyway.) There are probably good theory books or pages out there. There may even be sample code on the NET -- but of course any open-source antiviral code probably has a higher chance of being fooled by viruses, simply because the bad guys will be able to examine it line-by-line and find its weak points. (That's not an attack on open source, BTW, of which I am a fan -- it's just indicative of an unfortunate consequence stemming from the otherwise-goodness of open information.)