As a programmer of any level, I have found that at times our programming knowledge comes to a halt. Some tend to dismiss this halt and that we are in it. We say things such as: "Well I know this, therefore I must know that." We use the words like: easy and simple; Without really looking at the problem in a greater detail.

So my questions are:

  1. What are we dealing with, how is this void formed?
  2. How do you get out of such barrier/mind set?
  3. How did you continue learning programming the right way?
+3  A: 

I suggest competitive programming. When you compete with smarter people you see that you have much to improve. Register at Topcoder if you did not register yet.

+7  A: 

Technology is moving much faster today than it was even 10 years ago. Languages and patterns emerge quickly. In my opinon the speed at which new "stuff" comes out is a slight problem because it doesn't give current "stuff" a chance to stabilize and standardize on anything. I think this leads to frustrations for the best of us, we learn something new, and it goes away before we can start to produce some good production code in it. I suggest staying off the bleeding edge. Wait for something to be around and usefull for a period of time before you invest in it. This increases your likely hood of learning a proven technology and that it will stay around long enough to be beneficial.

Yes, I kind of see what you are saying... I am getting attached to ASP.NET MVC lately because it is something that I understand maybe because it has been around for a long time?
Ehm ... a what? Something with .NET in it as being around a long time ... I guess time is relative.
+8  A: 

I would suggest trying a different programming language. Lisp or Scheme will challenge your programming mindset if you've been in C-syntax land too long.

Matt Garrison
More to the point, try a programming *paradigm* you haven't used yet. Getting used to a new syntax isn't all that challenging. I suppose if you've been monoculturizing yourself with just one programming language, it's a good first step, though.
Jan Krüger
I tried to get into objective-c and find myself frustrated at times with it because it doesn't feel like java or c# and then I end up quitting...
Objective-C isn't a new paradigm, it's just a horrible syntax :P
@Andrew: well, there's not just java, c# and obj-c in the world. There are dozens of other languages you can look at.
Jan Krüger
If it's challenging your mindset you want, then I'd recommend Haskell.
Most of these commentators have missed the point... Java, C#, objective-c are all of a family. Lisp and Scheme are _fundamentally_ different in a way that you can't understand if you haven't programmed in a language of that family before.
Paul McMillan
+45  A: 

I think programmers often equate "learning" with "learning new technologies", which I think is a mistake. A new technology, when looked at purely technically, may not seem all that new and different; there's no perceived need to add tools if the ones you have are working. Additionally, the universe of potential new technologies to learn is so enormous that inertia is a natural response.

Better than focusing on technologies, I think, is to focus on learning better practices (e.g. testing, dependency injection, REST, DRY, the SOLID principles, etc.), learning new approaches and methodologies (e.g. TDD, BDD, specific varieties of Agile), learning new "softer skills" (e.g. estimation, project management). I often find that the technical skills come almost without thinking about it when I plunge into a new paradigm in this way.

It's also good to move into new domains and let that drive your learning -- if you always done database-driven web applications, try something completely different. (Do you have a smartphone or PDA? Try writing a small app for that.) Set yourself programming practice projects (take a look at Project Euler, for example). Try using a programming language of a completely different paradigm; going from object-oriented to functional, for example (moving to a new syntax probably isn't novel enough; I mean a completely new mindset).

Lastly, when I get into this mindset, I re-read The Pragmatic Programmer, which always reminds me that I'm not writing code at the standard I could. Sure, I try to obey the DRY principle, but I can't avoid some repetition. Sure, I decouple my classes, but maybe I could do more. The book paints a picture of a higher level of quality than I've ever quite managed. This acts as a gentle kick in the posterior.

+1 Totally agree about the learning new stuff. I'm also a big fan of The Pragmatic Programmer. Also, The Mythical Man Month is an interesting read.
Sune Rievers
As a side note, generic code can be 3 times as complex as single-use code (I rememebr someone citing a study...) - so *some* repetition isn't bad by default.
@Sune Rievers: You already mentioned "The Pragmatic Programmer" - That is the first book I would recommend!Another book I would recommend - if you have some Perl knowledge - is "Advanced Perl Programming". It has not been updated since more then 10 years. Last week I read some chapters again and I was quite impressed how much "forgotten" design approaches I have re-discovered!
+4  A: 

Here's a piece of classic wisdom: you can learn most by taking apart interesting things and finding out how they work. Dismissing things as easy does work against that, of course, so get yourself the code of something really complex and try puzzling out what's going on. That just might increase your motivation to dive into slightly simpler things, too.

Other than that, the best choice is to find yourself someone who's slightly (but not orders of magnitude) better than you, and work with that person on some project, similar to pair programming in "XP".

In the end, the most efficient way to absorb new knowledge and new perspectives is to dive head first into an environment that has these things.

Jan Krüger
I guess I have lost that too, many of my peers are just like me so it is hard to jump onto a project with them, especially from scratch. I do like puzzles so taking things apart like other peoples code has always been interesting to me.
+8  A: 

Pick something you don't know at all, and learn a little about it.

  1. Hardware programming - the Arduino.
  2. New frameworks - Ruby on Rails.
  3. New UI layers - Ajax (jQuery, GWT, etc.)
  4. Replacements for SQL - Apache Cassandra, Hadoop
  5. Join an open source project, and make a contribution to at least two releases.

Or just read a book on software engineering; it's hard to go wrong with Code Complete or The Pragmatic Programmer.

Dean J
+1 for Arduino!
+4  A: 

Learning "softer" skills (TDD, modeling, etc) is good, and another approach you might take is to learn something else entirely. For example, hockey (or some other team sport), or knot making, or tango, or little theater.

Programmers often perceive "learning" and "smartness" to be tied to technology in general and computers in particular. Try something very different.

One result of doing so will be exposure to people who learn and think in different ways. This can inspire you to go back and tackle new technology.

Liz Albin
TDD is so not a soft skill. It's totally technical and measurable, but it is something you get better at over time rather than something binary you can either do or not do.
+5  A: 

Read Passionate Programmer!!! It is like the 7 habits for highly effective people book for programmers. The book, apart from telling you to do right things, it motivates you to do them.

+5  A: 

Join an open source project in an area you aren't too familiar with but have some interest in. Like, oh a web service framework if that floats your boat. You'll learn about the problem domain. You'll learn about how people succeed and fail in working together in these projects. You'll learn about the tools and techniques used by the community.

+24  A: 

If you are a programmer and really want to learn things that take you into a new level, I strongly suggest that you study non-programming subjects that can make you a better programmer.

These are some subjects that I have studied and found extremely useful:

  • Cognitive psychology. It explains how people perceive and communicate information; it's the basis of conceptual modelling.
  • Organisational theory. It provides a good framework to understand the context where most information systems work.
  • Management "science" and people skills. It can give you clues about the social factors and motivations that interact with software systems.
  • Linguistics. Natural languages may be formal systems, after all, and thinking in terms of lexicon, syntax and semantics is always useful for software people.
  • Architecture (the one making houses and buildings, not software). Its abstract nature and the use of patterns make it a great exercise for the mind.

In general, anything involving formalisms would do you good. Anything that involves people plus information together is also very useful.

Hope this helps.

This is actually a good point that I will keep in mind, after getting into programming I have really never focused on anything but coding and theory of coding. I have never really gotten into the sciences or mathematics behind programming. Thank you for your thoughts.
You are most welcome. :-)
You could explain why you chose each of those topics/why you think they are useful for programmers. For instance, why are Architecture and Linguistics included on the list?
@luiscubal: As I said, those are subjects that I personally found useful. It is a subjective judgment. In general, anything related to the use of formalisms will help your mind reason formally, which is what you need to do in software, so linguistics and architecture are in. Also, I found people-related subjects useful because software folks tend to focus too much on the machine and too little on the users, so management and organisational theory are also in. Management, in addition, teaches you how the contexts for most information systems work. (TBC)
@luiscubal: Finally, psychology is about how we perceive and communicate what surrounds us, and that is the foundation of conceptual modelling, on which much programming is built. I hope this brief explanation helps. I am happy to discuss, though. :-)
Good point. To elaborate a bit - Design Patterns are based off the same idea in architecture. Linguistics are useful for designing a computer language - it's more than just telling the computer what to do. If you are designing a GUI, psychologists have done lots of studies about how we perceive things. And the more you get involved with developing software, the more it becomes people skills and management.
Mark Krenitsky
@Mark: absolutely.
I would add discrete mathematics to that list!
Gab Royer
@Gab: Yes, indeed. Discrete maths are crucial. I tried to list subjects that are, in principle, totally unrelated to computing; that's why I avoided anything related to maths. But I agree with you. :-)
I would add Human Factors Engineering to the list.
+4  A: 

I would recommend trying to learn something that has nothing to do with programming, which is more difficult than it appears. Ideally it will be challenging and will break you of this habit.

+9  A: 

I have experienced this somewhat. I too like to explore new things but I usually find I need a reason to do so. Like, 'Learning LISP would be interesting, but what good would it do me?' I am always reading posts from guys who just toy around with some random language in some random environment and I wonder why they commit so much time to something that is pretty useless.
Its easy to get into that hole where you do not want to do anything because you cannot easily see the merits behind it. My strategy for overcoming these trenches is usually to move on. Change your environment, find a program at work that could use some creative updates.. etc.

I always find working on projects that benefit me as the best motivation to learn new things. If I see something that could be improved by a redesign or a new pattern I just read a bit about on wikipedia I jump on it. I learn all there is to know about it, write up the project, make sure its perfect, then move on.

This works best in an environment where you are not 100% confident in your knowledge, that way you can see something that you think could be improved, but after research and a bit of consultation you find out you were wrong. And trust me, there is no better lesson then realizing that your initial hypothesis was wrong.

What puts you in that void is the feeling of superiority, the thought 'Yea, I would do it this way, but its not worth my time.' Will kill any and all motivation. If you consistently find your initial thoughts wrong you never end up in that void because you are always underestimating your abilities.

These days I find motivation for new research and developing and learning new things out of the competition with my fellow programmers. I am constantly telling myself I do not know enough, and thanks to wikipedia, stumbleupon, and my RSS feed I am constantly reminded that there are better programmers out there and I still have a long way to go.

So with that in mind I try to put myself into situations where I do not know everything. Situations where I can pick up a broken system, apply some changes, maybe redesign the entire thing, and put it back down to move onto the next. It keeps things interesting, it keeps me motivated, and it makes me a better programmer.

+8  A: 

Rather than thinking you know something by transitivity, try actually doing those things. For example, if you think that because you know C# that you should know Java due to their similarity, why not put that to the test.

The only way in which we learn is by doing things that we have never done before. If that's reading about concepts, theorms, and other ideas, then try creating an idea or a concept (however small) yourself. Make it something original and you will learn more about that subject than you ever thought you would need to know.

If you learn by writing actual code, by testing code, or some other means, do it. Rather than think that it should be easy, prove to yourself that it is easy. You will learn in the process and will kickstart your brain.

The best way to prove you've learned something afterwards is to show someone else and defend your work. If you wrote some code, show it to someone and ask them to review it. If you created an original idea, express it in writing and ask someone to review your argument / idea.

+5  A: 

Well, I'm not that experienced, but I'm trying to always have some book to read. I set my "page count" to minimum of 300 pages every month. This way I always learn something new, rediscover some old stuff etc.

Also, don't underestimate new technologies. Always try to read documentation and don't expect it to work as anything before.

Try to do something you might like and what you've never done before. 3d graphics, learn some new language or technology, whatever. Just don't force yourself into something you don't like, else you'd just end up frustrated even more.

Ondrej Slinták
I'm here and there on most of this answer, but I agree so so strongly with the final, bolded sentence that this becomes an easy +1.
+2  A: 

This is a really great question! Computers, computer science is such a unique study compared to any other field that exists. I have found myself in your shoes and still do many times. Technologies change rapidly and you should never be afraid of thiat. What you need to do, is arm yourself. It is good that you believe you can look at many problems in the same way. It is also good that you like problem solving. Programming is all a puzzle, in fact if you look at it; it is a never ending puzzle. Read, learn, practice, and repeat.

Measure yourself by what you do, and it’s not about doing things well! Let me explain, your target isn’t to write a perfect program, your target is to write a program and shape it to your needs. I mean think about it carefully, we are in a field where new technologies sprout every day, you can’t even come close to knowing it all. Most importantly avoid panic and fear, if you don’t know something raise your hand and ask (that’s what we are here for) don’t get scared into a corner. I have done this many times before and it’s not pretty.

I would recommend two books:

Coder to Developer by Mike Gunderloy

Leadership and Self Deception: Getting Out of the Box by The Arbinger Institute

I have actually read :) Leadership and Self Deception, this is a great book but it isn't really about learning, more about communication, which is important too :)
I finished reading Code to Developer. That is a great book, Thank You.
+1  A: 

Simply block Twitter at your company's proxy. Then productivity and learning gets back to normal.

That totally works for me!

Bruno Lucattelli
+5  A: 

This is a bit off center, but you can also focus on domain knowledge. After all, you're writing programs to do things, right? If you're writing a turn-by-turn navigation system, learn about GIS. If you're writing tax software, learn about accounting. You might not become a better programmer, per se, but you'll certainly improve at solving problems in your domain of choice. Plus, there's a good chance your domain knowledge will be useful long after your technology is obsolete. And if you don't have a domain, you can pick one that looks interesting.

Mark Krenitsky
+1. In my experience writing the program is the easy bit. Knowing what the client needs the program to do is so much harder.
Martin Brown
+1 It also gives a nice flat perspective of what components are of real value across systems and domains, which is invaluable when you get to write frameworks and foundational services.
Mike Burton
+3  A: 

What do you know? What don't you know? Ignore the former, focus on the latter.

+4  A: 

Learning and motivation are such personal subjects that it's difficult (impossible) to say with certainty what will work for you, but since I haven't seen this presented much, I offer:

If you find you're getting hung up forcing yourself to learn, then study what interests you, and cheerfully ignore that which does not.

It's easy to get discouraged and bogged down when learning becomes a terrible chore. It's good to force yourself through tough work at times, but if you've gotten nowhere for some time, it's time to just branch out a bit, and try something "interesting", regardless of whether it has any obvious value. Just work on a fun or interesting project. You can reenergize yourself, and perhaps regain an enthusiasm in learning something new when it has a practical application with the project you're already working on.

+4  A: 

You could always teach at your local school district and pass on some knowledge as well as gain new perspectives on programming.

+4  A: 

One thing I try to do is look for ways to improve the processes that are in existence in the organization / group and try to increase productivity, ease of use etc.

You are on the right track by being on Stack Overflow.

Read some blogs, there are a lot of smart people out there sharing their ideas and techniques.

When someone says "You don't need to learn that, we already have a way to do that here" Challenge the status quo and do some research looking for a better way

+2  A: 

Find a new project. Perhaps something to work on in your personal time. If you can come up with an idea, pursue it! If you're having trouble coming up with one, look for an open source project to join. You can even browse around here to find questions that you know you couldn't answer.

I've found that I've learned the most when trying something new. Finding new problems to solve will help push you. And I think motivation is going to play a large role in getting you out of your 'funk.'

John D.
+3  A: 
  1. Sometimes the barrier relates to a state known as burnout. Other times, it is merely a lack of motivation, possibly in response to negative reactions in the past when completing things.
  2. Sometimes by changing jobs or which tasks I'm completing. Changing the focus can be useful in some cases. In other cases, it can be asking "Why?" recursively that is useful at times.
  3. I didn't and don't think there is "the right way" to learn programming. What may work well for me to pick up something quickly may be terrible for the next guy or vice versa. I'd also note that sometimes by doing things the wrong way, one may serendipitiously discover what may appear to be an optimal way, but that may be an illusion.

PS - Am I alone in thinking of the type void rather than the concept of a mental block? Maybe I've been around C and its derivatives too long...

JB King
ha ha, nope I thought about it too, I agree with you on the subject, though in this case it is more for learning then a burnout, sometimes it is just hard for some, to jump around into new subjects in development. :)
+3  A: 

The more you learn you realize there's even more that you don't know

So you can keep learning and there will always be new stuff, consider knowledge, as in experience, not just technology, think about people knowledge and so on. Once you feel comfortable enough with your technical knowledge think about:

  • do you know how to manage a team to get task completed (maybe a bigger project)
  • do you know how do you manage code repository for a team of developers working on the same codebase - you may not be required to actually manage the code but someone may ask you for advice how to set it up on your new project or propose strategy to use
  • do you know how do you estimate time/cost of your work
  • do you know how to bill your customer, what kind of support/development contracts you can offer
+5  A: 

You're lucky, this is actually a research question! Andy Ko looked at beginning programmers and identified the barriers that kept them from being able to solve the posed problems. Here's the paper: Six Learning Barriers in End-User Programming Systems.

Update: Here's a summary, assembled from the paper. The numbers indicate how often the barrier occured:

The six barriers we identified are: design, selection, coordination, use, understanding, and information barriers.

  • Design barriers (4 of 130) are inherent cognitive difficulties of a programming problem, separate from the notation used to represent a solution (i.e., words, diagrams, code).
  • Selection barriers (13 of 130) are properties of an environment’s facilities for finding what programming interfaces are available and which can be used to achieve a particular behavior.
  • Coordination barriers (25 of 130) are a programming system’s limits on how programming interfaces in its language and libraries can be combined to achieve complex behaviors—what one learner called “the invisible rules.”
  • Use barriers (36 of 130) are properties of a programming interface that obscure (1) in what ways it can be used, (2) how to use it, and (3) what effect such uses will have. These arose when learners knew what interface to use, but were misled by these obscurities.
  • Understanding barriers (38 of 130) are properties of a program’s external behavior (including compile- and run-time errors) that obscure what a program did or did not do at compile or runtime. These emerged when learners could not evaluate their program’s behavior relative to their expectations.
  • Information barriers (14 of 130) are properties of an environment that make it difficult to acquire information about a program’s internal behavior (i.e., a variable’s value, what calls what). These arose when learners had a hypothesis about their program’s internal behavior, but were unable to find or use the environment’s facilities to test their hypothesis.
Wow, started reading this, this is great.
Yea, Andy Ko is really fantastic. He's kind of a one man show as a researcher, meaning that he's kind of alone in a field that he hopes to get started now: using the methods of psychology to get insights to the difficulties in programming. Wish I were him :)
+4  A: 

Get out of your comfort zone and learn more about the business that you may be working for, the current industry expectations, and what these businesses are really looking for.

Higher-level developers must remember that most of the technology has evolved out of some sort of need. Sometimes this need is highly technical (e.g., working around some technical limitations) and sometimes it's purely business driven. It's this sort of need and mindset which drives the creation of frameworks & technologies and even general engineering approaches.

In a nutshell, broaden the problem domain that you're looking to attack and you'll realize just how much there is to learn.

+4  A: 

If all you've ever written is single-use application code, writing some very generic open-source libraries could be a real eye opener. It's a difficult but interesting challenge to design code that has to be useful in a variety of use cases from completely different problem domains. This is an especially good experience if it introduces you to new programming techniques in the process. For example, writing generic libraries for the D programming language was what made me understand lazy evaluation semantics.

+3  A: 

Maybe you are too much focused on the "result" ? That's pretty much OK if you have a concrete project to work on.

But software engineers tend to do "architectural/programming stuff" only.

Maybe you you cannot force to break this kind of "barrier" and it's better to try something that is completely different from software development:

  • grab a bicyle and use it daily to ride to work (if that's possible regarding the distance)
  • visit collections of modern arts (even if you think "that's nothing for me")
  • meet people/friends and play card games with them
  • hand crafting (recently I got a sewing machine for nothing - and I was surprised how challenging this is)

That might help - or it might not help.

If it doesn't help regarding the "barrier" you have mentioned it will anyway give you new experiences.