Occasionally I see questions about edge cases on Stack Overflow that are easily answered by the likes of Jon Skeet or Eric Lippert—experts who demonstrate a deep knowledge of a particular language and its many intricacies. Here's an example of this from Lippert's MSDN blog:

You might think that in order to use a foreach loop, the collection you are iterating over must implement IEnumerable or IEnumerable. But as it turns out, that is not actually a requirement. What is required is that the type of the collection must have a public method called GetEnumerator, and that must return some type that has a public property getter called Current and a public method MoveNext that returns a bool. If the compiler can determine that all of those requirements are met then the code is generated to use those methods. Only if those requirements are not met do we check to see if the object implements IEnumerable or IEnumerable.

This is cool stuff to know. I can understand why Eric knows this; he's on the compiler team, so it's explicitly in his job description to know.

But how do mere mortals, those of us on the outside, find out about stuff like this?

Answer: A Message from Mr. Lippert (18 Votes)

If you want to get a deep knowledge of C# it is undoubtedly an advantage to have the language specification, ten years of design notes, the source code, the bug database, and Anders, Mads, Scott and Peter just down the hall. I'm certainly fortunate, no question about it.

However, even without those advantages it is still possible to get a deep knowledge of the subject.

Back when I started at Microsoft I was working on the JScript interpreter that shipped with Internet Explorer 3. My manager at the time told me something that was some of the best advice I've ever gotten. He said that he wanted me to become the recognized expert at Microsoft on the syntax and semantics of the JScript language, and that I should go about this by seeking out questions on those aspects of JScript and answering them. Particularly answering the questions I didn't know the answers to, because those are the ones I would learn from.

Obviously Stack Overflow and other public Q&A forums are like drinking from a firehose for that sort of thing. Back then, I read comp.lang.javascript and our internal Microsoft "JS User" forums religiously and followed my manager's advice: when I saw a question that was about the language semantics that I didn't know the answer to, I made it my business to find out.

If you want to do a "deep dive" like that, you've got to choose carefully. To this day, I am remarkably ignorant of how the browser object model works. Since I have been concentrating on becoming the C# language expert these last years, I am remarkably ignorant of how the various classes in the base class libraries work. I am fortunate in that I have a job that prizes specific deep knowledge; if your job or your talents are more in line with being a generalist, going deep might not work for you.

Writing a blog is also tremendously helpful; by requiring me to explain complex topics to other people, I am forced to confront my own inadequate understanding of various topics all the time.

Answer: One Problem at a Time (14 Votes)

Having been on the "guru" side of the conversation once or twice, I can tell you that a lot of times what you perceive as "deep knowledge" is often the result of the "guru" recently struggling for a month to solve the problem you're trying to solve yourself. That's especially true on a forum where people can choose which questions they will answer. Even the likes of Jon Skeet and Eric Lippert had to learn "hello world" at one point. They pick up their knowledge one concept at a time, same as anyone else.

Answer: A Multipronged Approach (4 Votes)

After learning a relatively useful stack of languages (the ones you need for a real job) at the level where you can do most common tasks, stop learning more languages until you have studied at least one in depth. Part of the problem in our industry right now, in my opinion, is that people only learn the first 5-10% of the language before moving on to some other language. Once you have the capability to do most common tasks in a job, then start looking at one thing in depth. (You can go back to getting breadth after you get some depth, then go back and forth between the two.)

Volunteer for the more complex, harder tasks, the ones that make you go in-depth to solve the problems. If there are none where you work, look for open source tasks or start working on a personal project that will make go in-depth. If your job has no interesting problems, consider looking for a more challenging job.

Read the advanced books on one language (for SQl Server for instance this would include reading about performance tuning and database internals) instead of the "How to Learn X in 30 Days" type of books.

Read interesting questions where they are asked and try to solve some yourself. If you want to learn, try to solve some without reading the other answers first. Even if the question has already been answered, you will learn more if you find the answer yourself. You might even find a better answer than the one the question had.

Ask a few of the harder questions. Evaluate the answers you are given, don't just use them. Make sure to understand why the answer would or would not work. Use those answers as a starting place to research.

Find some good technical blogs from known experts in the field and read them.

Stop throwing away your knowledge after you are finished with it. Learn to retain. Most experts don't have to look up the common syntax. They don't have to reinvent the wheel every time they face a problem because they remember how they approached a simliar problem before. They can connect the dots and see how problem X that they did two years ago is similar to problem Y that they have right now (it amazes me how few people seem able to make connections like that).

Answer: Decompile & Read (3 Votes)

Get Reflector or any other decompiler (since Reflector's fee-based now), and start opening up some of the most used .NET libraries to learn how the internals work. Combined with a book like CLR via C# you'll get quite deep (deeper than most of us will go on their regular job).

91 Reader Comments

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Get crackin!

My understanding was to spend some 10000 hours doing something.

Some people say 10000 hours; some people (an article I read a while ago --- don't remember where, though) say 10 years. I'll call you an expert when you're dreaming in code and wake up with solutions

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Get crackin!

My understanding was to spend some 10000 hours doing something.

Some people say 10000 hours; some people (an article I read a while ago --- don't remember where, though) say 10 years. I'll call you an expert when you're dreaming in code and wake up with solutions

Well if you spend 2-3 hours a day, you will come out at around 10 years after spending 10000 hours.

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Get crackin!

That only works for topics that are accessible to the average Joe such as programming. Others, such as engineering and physics, require years of formal schooling that is not easily bypassed by simply dumping a lot of time and effort into it.

I would focus on two points. One is that people learn stuff by doing something with it. The primary way to learn a programming language is by writing code with it. No doubt answering questions is a supplementary approach that is useful for someone who is particularly interested in and good at programming languages. But, the second point is that knowledge about a programming language is not usually a particularly important skill for a software engineer. Unless you are someone who, like Eric Lippert, has a job creating porgramming tools, your most important skill is going to be understanding the problem domain that your software algorithms are modeling. You will be stuck with whatever software technology is being used in your workplace. In my experience, even the best software engineers were doing well if they managed to learn one technology well.

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Get crackin!

My understanding was to spend some 10000 hours doing something.

Some people say 10000 hours; some people (an article I read a while ago --- don't remember where, though) say 10 years. I'll call you an expert when you're dreaming in code and wake up with solutions

Well if you spend 2-3 hours a day, you will come out at around 10 years after spending 10000 hours.

True, but then there are the folks that do it for 10+ hours a day for 10 years...so what does that make them?

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Get crackin!

My understanding was to spend some 10000 hours doing something.

Some people say 10000 hours; some people (an article I read a while ago --- don't remember where, though) say 10 years. I'll call you an expert when you're dreaming in code and wake up with solutions

Well if you spend 2-3 hours a day, you will come out at around 10 years after spending 10000 hours.

True, but then there are the folks that do it for 10+ hours a day for 10 years...so what does that make them?

I think that programming is mostly like fractals, you can iterate around something and discover more details and view points that can be useful. Each technique can help you to discover new details or viewpoints and how to use these. The diversity is recommended, but the dev-log is a concentrated that provides technical details and utilization.

when I wanted to learn .NET I built a media player (a clone of then winamp) in Winforms. a few years later when WPF was introduced I rewrote the entire application to study the new platform... same thing happened shortly after that when LINQ was introduced but this time I rewrote the entire backend of the media player while the GUI didn't need to change... I've since added a 'cloud' player that receives streamed media from my media player.. all an attempt to study ajax and html5 more closely...

when building a large application you have to study many new aspects of things you may have never considered. for instance with the WPF version of my media player I had to learn about threads and observable collections to have the player scan for media in the background, I had to learn about COM interops because there was a lot of missing functionality in the initial version of WPF (like a full screen window), I had to learn how to interact with device drivers so that I could transfer media to an android device

when I started the project I never imagined ever having to use most of these things.. but I'm glad I put the time in to learn it

Doing a ton of new stuff in one particular field for a long time will get you deep technical knowledge of anything you want to get in to. The accepted viewpoint on this is that one needs ten years of continuous practice and experience to become an expert.

Get crackin!

That only works for topics that are accessible to the average Joe such as programming. Others, such as engineering and physics, require years of formal schooling that is not easily bypassed by simply dumping a lot of time and effort into it.

Be careful with that last suggestion. Remember that even experts can write bad code and the base class library authors are no exception. Just today I opened up System.Data.Common.DbConnectionOptions.GetKeyValuePair to try to debug a weird exception and was confronted with this hideous mess. It's interesting to see how they solved this parsing problem but at the same time I wouldn't want anyone learning from this implementation.

Get crackin![/quote]That only works for topics that are accessible to the average Joe such as programming. Others, such as engineering and physics, require years of formal schooling that is not easily bypassed by simply dumping a lot of time and effort into it.[/quote]

I don't understand the distinction you're making... There is a spectrum of difficulty and sophistication across all three subjects. There are high quality textbooks on physics and engineering available at the nearest university library. You can learn a lot via self study, but it takes time and effort.

On the other hand, to reach expert level, I think you need some form of mentorship for guidance and feedback. But how does that apply any less to programming than it does to physics and engineering?

I don't understand the distinction you're making... There is a spectrum of difficulty and sophistication across all three subjects. There are high quality textbooks on physics and engineering available at the nearest university library. You can learn a lot via self study, but it takes time and effort.

On the other hand, to reach expert level, I think you need some form of mentorship for guidance and feedback. But how does that apply any less to programming than it does to physics and engineering?

The distinction is that some subjects require a broader foundation that is very difficult to self teach. That's what you're paying for at college. You cannot pick up a 'learn X in 24 hours' book and be churning out functional (albeit sloppy) work in a couple weeks.

I think the gist of gaining expert knowledge is to *think* deeply about the thing. The meat and potatoes question is often How does it work? But the gold is in understanding Why. Always find the opportunity to at least ponder it for a little while.

Be careful with that last suggestion. Remember that even experts can write bad code and the base class library authors are no exception. Just today I opened up System.Data.Common.DbConnectionOptions.GetKeyValuePair to try to debug a weird exception and was confronted with this hideous mess. It's interesting to see how they solved this parsing problem but at the same time I wouldn't want anyone learning from this implementation.

Is that decompiled code? The use of gotos and automatically generated label names suggests so. If it is, I wouldn't regard the appearance of the code as representative of what was actually written.

Be careful with that last suggestion. Remember that even experts can write bad code and the base class library authors are no exception. Just today I opened up System.Data.Common.DbConnectionOptions.GetKeyValuePair to try to debug a weird exception and was confronted with this hideous mess. It's interesting to see how they solved this parsing problem but at the same time I wouldn't want anyone learning from this implementation.

Is that decompiled code? The use of gotos and automatically generated label names suggests so. If it is, I wouldn't regard the appearance of the code as representative of what was actually written.

It is decompiled. I'm not sure how JustDecompile works, it seems to sometimes come up with code that is very similar to the original code and sometimes comes out with a mess like what I posted. I suspect it has to do with whether or not debug symbols are available but you can see that even private members have retained their names so I guess I don't really know enough about IL bytecode to know where this information comes from.

Even despite the GOTOs and other stylistic issues which are probably decompile artifacts there are some serious red flags in that method. It's huge, it has some special cases (if (useOdbcRules || 61 != chr) etc) which in my opinion don't belong at this level of abstraction.

Be careful with that last suggestion. Remember that even experts can write bad code and the base class library authors are no exception. Just today I opened up System.Data.Common.DbConnectionOptions.GetKeyValuePair to try to debug a weird exception and was confronted with this hideous mess. It's interesting to see how they solved this parsing problem but at the same time I wouldn't want anyone learning from this implementation.

Is that decompiled code? The use of gotos and automatically generated label names suggests so. If it is, I wouldn't regard the appearance of the code as representative of what was actually written.

It is decompiled. I'm not sure how JustDecompile works, it seems to sometimes come up with code that is very similar to the original code and sometimes comes out with a mess like what I posted. I suspect it has to do with whether or not debug symbols are available but you can see that even private members have retained their names so I guess I don't really know enough about IL bytecode to know where this information comes from.

Even with debug symbols, it's still guessing at the code structure. I suspect that it looked quite a bit less awful when it was written. Now, that doesn't mean it necessarily looked good--just less awful!

Be careful with that last suggestion. Remember that even experts can write bad code and the base class library authors are no exception. Just today I opened up System.Data.Common.DbConnectionOptions.GetKeyValuePair to try to debug a weird exception and was confronted with this hideous mess. It's interesting to see how they solved this parsing problem but at the same time I wouldn't want anyone learning from this implementation.

I've seen way worse parser code. I've written some ugly ones in C and x86 assembly myself that are incredibly fast but often unreadable unless they're well commented.

Back to the subject, I think programming languages are one of those things that are really easy to pick up once you have a lot of theoretical background on the subject. The libraries are, at least for me, the slow part of getting really productive with a new language. Especially when poor name conventions are used.

Not to dissuade anyone from learning new languages, but...do everyone a favor and learn how to write well formed and concise code. Simple is better, from a visual standpoint and often from a compilers perspective. Once you get good at that, take a lot of time and learn what your code does under the hood. Its a bit hard to see low level stuff from a VM code perspective, but get a good compiled language and start dumping some assembly and actually see what your generating. If you get really good at that, then maybe start designing your own simple compiler (see the dragon book) If you get really good at that too then go off the deep end and design your own simple fetch execute engine for a spartan 3 ( or other cheap fpga).

You really have to do a lot of this kind of research in your free time. Work usually doesn't allow you to take the extra time to learn the kind of language depth we're talking about. In fact I've worked with quite a few people who spend way too much time looking for the perfect hack. They produce awesome code, but waaaaaay too slowly. Just my 2c

I've never done any programming prior to this year, started learning Python in January, and last week wrote my first Nagios plugin!! Couldn't be happier.

I had done every tutorial i could find, Lynda.com, VTC.com, thenewboston, etc but the one that worked the best was learnpythonthehardway.com. It got you to actually write out all the code, and to solve a few small problems after each chapter, instead of just reading or watching videos where you do learn it, but when it comes to writing it out you draw blanks. Well that's my advice to anyone starting out.

I really hate programmers, they think they are smart but work the same way than 40 years ago.

Find a 1970 computer and you will see how different is from a today phone, xbox kinnect or ipad. This "smart" guys are still programming using the command line. There is no serious visual programming tools that works. No, you need to write commands in text like I was doing in my spectrum.

Please, do not be so smart and find a way who let normal people program. You can retouch a pic, build a web page, create a video in a simple way these days, but cannot program a simple software because you need to be so smart to understand how to write outdated commands works.

I really hate programmers, they think they are smart but work the same way than 40 years ago.

Find a 1970 computer and you will see how different is from a today phone, xbox kinnect or ipad. This "smart" guys are still programming using the command line. There is no serious visual programming tools that works. No, you need to write commands in text like I was doing in my spectrum.

Please, do not be so smart and find a way who let normal people program. You can retouch a pic, build a web page, create a video in a simple way these days, but cannot program a simple software because you need to be so smart to understand how to write outdated commands works.

Now I've heard the 10,000 hour theory.. but let me hack a statement from John Nash. "Some of you will spend the better part of 3 months trying to solve this problem, the rest of you will spend an entire lifetime".

My advice, or actually the advice that was passed on to me. Find a project. Too many people just do whatever work they're given. Like the guy in the article said, even working at MS isn't a sign that you made it far enough.

Seriously. It's in the documentation, nine times out of ten. It's only in that tenth case that you need personal, expert experience.

The apparently random duck typing that C# (and later adapted elsewhere) for enumerators is pretty off-putting though. You can read the documentation and still not appreciate it because it's something you can't do yourself generally in your own code.

I really hate programmers, they think they are smart but work the same way than 40 years ago.

Find a 1970 computer and you will see how different is from a today phone, xbox kinnect or ipad. This "smart" guys are still programming using the command line. There is no serious visual programming tools that works. No, you need to write commands in text like I was doing in my spectrum.

Please, do not be so smart and find a way who let normal people program. You can retouch a pic, build a web page, create a video in a simple way these days, but cannot program a simple software because you need to be so smart to understand how to write outdated commands works.

It's all a Freemason/Illuminati conspiracy to keep the plebs from knowing the deeper secrets of the cult.

Be careful with that last suggestion. Remember that even experts can write bad code and the base class library authors are no exception. Just today I opened up System.Data.Common.DbConnectionOptions.GetKeyValuePair to try to debug a weird exception and was confronted with this hideous mess. It's interesting to see how they solved this parsing problem but at the same time I wouldn't want anyone learning from this implementation.

EDIT: EDIT: EDIT: Okay, so let's assume I'm right (who knows, it happens), and we're being constructive to the youngsters. How did I know this? Firstly, I've decompiled my own code, and enough of other people's code to see this before. And secondly, at somepoint I read Jeffery Richter's CLR via C# book (it was .Net 1.0 or 1.1 at the time).

The point is the CLR (the thing underneath .Net) doesn't have a concept of "switch" it just has gotos (aside: gotos have their place) -- it'd be the same thing, I imagine, in the (for instance) Java world. You can learn your language, but to find out how things really work you go deeper.

In c/c++ you start learning about all sorts of things that lead to learning a little bit about assembler, in C# and other byte-code languages you learn about how the byte-machine works.

And eventually, you end up at the CPU -- we're talking cache and TLB and stuff I know only by name.

There is also the chance I'm wrong, and the guy/girl who wrote the code in the pastebin sample actually wrote the code like that. Firstly... well, it's unlikely. If that's the case it was probably written in byte-code, because it's such an old-school way of coding it just isn't done like that anymore except by guys fatter and with bigger beards than me (I have no beard, btw). Perhaps it was written in .Net 1.0 prior to C# taking shape, but there's (I imagine) it has 0% chance passing code-review anywhere.

I don't regard obscure functionality in a commercial API as deep programming knowledge.

Bearing in mind that programming is ALWAYS the creation of a virtual machine of some kind (and ultimately, a virtual machine that is exposed to the client), it pays to develop some exposure to other virtual machines and ways of thinking that are out there. I would regard Smalltalk, Prolog, OMeta and similar technologies as good candidates for "brain expansion". Read AI texts. Explore heuristic search, parsing, neural nets, probabilistic logic, etc. This assumes that you've got the basics right, e.g. know when you're coding an NP-complete algorithm, understand data structures, etc.

I don't regard obscure functionality in a commercial API as deep programming knowledge.

Bearing in mind that programming is ALWAYS the creation of a virtual machine of some kind (and ultimately, a virtual machine that is exposed to the client), it pays to develop some exposure to other virtual machines and ways of thinking that are out there. I would regard Smalltalk, Prolog, OMeta and similar technologies as good candidates for "brain expansion". Read AI texts. Explore heuristic search, parsing, neural nets, probabilistic logic, etc. This assumes that you've got the basics right, e.g. know when you're coding an NP-complete algorithm, understand data structures, etc.

Always a virtual machine... really? I wouldn't classify assembler as a virtual machine, nor any of the compiled-to-machine code languages as virtual. By definition (I thought) they are exactly the opposite of virtual.

Really interesting subject and I think we could all gain a lot by debating this more in depth.Although there are some good advice in the article, it's way too short and vague to really make much of a difference I'm afraid.

Given that you are already a programmer and you strive to improve your skills, here's my advice:

- Be curious and explore technologies - to gain in depth knowledge in an area you need a broad foundation.- Get familiar with the framework documentation- Learn to master Google - everyone can use google, but mastering Google can be key to finding answers and helpful information when working in areas where only a handful of people have been struggling with the same problem as you.- Read a book! It's surprising how few developers actually reads technical books - if you read just 1 book a year on a given subject, your theoretical foundation in the area are probably ahead of 90% of your colleagues!- Learn the innards of the platform your developing on, this will help you dramatically in understanding how things work and when no one else knows the answer to your problem, this is key to working it out yourself - this might make the difference between being an experienced developer or a guru! If developing for Windows this means reading Windows Internals by Mark Russinovich - if developing for .NET _also_ read CLR via C# by Jeffrey Richter. In these multi-core CPU days I also believe Concurrent Programming on Windows by Joe Duffy should be mandatory reading!- Be obsessive about code structuring! Strive to master code structuring so it is readable and maintainable - in many cases this means creating more libraries, more classes and more functions than you would normally be inclined to. Keep things as simple as possible and make your code self-documenting. This will take years to master, but that's no excuse for not starting today!- Gain business knowledge. If doing e-commerce, learn about order management, stock management, online marketing, business intelligence and so forth. Also learn about manegement and how managers think, as these will often be your "customers".- Learn to do prototyping and design your solutions before committing yourself to code. This might sound like something you learned in school, but people tend to forget about these practises once out in the "real world". Committing yourself to code early in the project, means redoing/refactoring a lot of things later and waste a lot of time because you did not want to spend a couple of hours designing the UI or the database of your solution before you plunged into coding.- Learn to master debugging. This is the one thing new (and also seasened!) developers spent waaaay too much time on. NEVER make assumptions about anything when debugging, _verify_! It might seem like this will take longer than just trying whatever best guess you have - but it will make sure you have found the solution in less than 5 minutes in 99% of all cases. Whereas I often see people who keep guessing for a solution spending hours on trivial debugging scenarios.- Learn to master production debugging tools. This is very different from development debugging! This is how you figure out what causes issues you only experience on your production systems. Many developers are lost when facing these issues, but it's a really fascinating area and people who master this are often looked upon as gurus (or perhaps a little insane). This means mastering how to gather crash dumps and analyse these with tools such as WinDBG (Recommended reading: "Advanced Windows Debugging" and "Advanced .NET Debugging")

Always a virtual machine... really? I wouldn't classify assembler as a virtual machine, nor any of the compiled-to-machine code languages as virtual. By definition (I thought) they are exactly the opposite of virtual.

I'm merely curious -- is there something I've missed?

It's virtual because you're not hardwiring transistor logic gates. Are you trying merely to be pedantic?

Always a virtual machine... really? I wouldn't classify assembler as a virtual machine, nor any of the compiled-to-machine code languages as virtual. By definition (I thought) they are exactly the opposite of virtual.

I'm merely curious -- is there something I've missed?

It's virtual because you're not hardwiring transistor logic gates. Are you trying merely to be pedantic?