I believe that there are two ways to get good at anything, "push" and "pull".
Push: You learn from books, classes, mentors, and studying examples, then apply what you have learned.
Pull: You have a problem that you must solve, then you learn what you need, any way you can, to build the solution.
I suppose there are pros and cons of each method, and I imagine that many people here have used some of both.
For the record, I am 100% Pull. I have absolutely no formal training. It took me 2 years to find my first job and then I was thrown into the deep end. It was simultaneously frustrating and exhilarating. There were so many times I didn't know what to do or didn't have enough "tools" in my box. So I had to figure it out and find sources of learning. But I always did. Any when I got that first thing working and then saw my customer's eyes light up, I was hooked.
Your CS degree may make you think that you're a "push" learner, but may I suggest that you adopt a "pull" approach. Forget what you think you know and find a job or a project or someone who has a real need. Then build what you need. You a several advantages over me: (a) It shouldn't take you long to find that job/demand/customer. Just keep looking. (b) You already have tools in your tool box, maybe not the right ones for the job, but you have something. And (c) It's easier than ever to adopt a "pull" approach. Help is everywhere.
You may feel frustrated, but I don't think you have a problem at all. You're in a great (and very normal) situation. Just adjust you attitude, find something to build, and do it.
The problem with pure pull is that you end up spending an inordinate amount of time reinventing the wheel, working towards one solution that you can see, while a much better and simpler solution is just around the corner because you don't have the breadth of knowledge to see past the sort of myopic view it provides.
On the other hand a pure push approach results in lack of practical knowledge, and frequently a "purity over pragmatism" mindset. As a guy who works regularly with grad students, this is frustrating -- the 100th argument consisting of me saying "yes I know the theory your professor taught, but here is how you do it for real given the bugs in the library implementation (or the runtime constraints or whatever)" gets pretty old too.
I guess I'm saying a pure approach for either has a tendency to miss a pile of benefits, and introduces it's own drawbacks.
Maybe the best thing to do is to try and sequence your "pushing" and "pulling." I actually graduated with a Political Science degree in 2009. I came to my first job not knowing a lick of programming, and the job didn't require it anyway. I got into programming because we were trying to do a website redesign and I wanted to help out. After we finished up that project, I kept going at because I liked it.
The first 9-12 months were tough. I read some beginner's books, wrote lots of really ugly code, and got things to work eventually, if only barely.
Then the code started to get prettier and more robust, and I picked up some more theoretical books like Leiserson's Intro to Algorithms to learn the theory. Having "pulled" around code for 9-12 months on my own, learning more formal computer science really allowed me to begin gluing those pieces together.
Everyone learns differently. Maybe a better approach for some CS programs would be to throw students into the water for their first year, let them struggle reinventing the wheel and solving practical problems as best they can, and then teach the theory and formalisms later?
I've taught computer science and I've seen that one's brain either understands computing concepts, or it doesn't. I've seen people with no programming experience pick it up pretty quickly. I've also seen people who were otherwise smart not get anywhere at all. If people can get past assignment, indirection, and boolean logic, they'll probably do fine. Understanding concurrency is also a sort of fundamental brain ability, but is something that fewer people have the ability for and is not necessary for every programming task.
It's funny, I used to be a pull person. I learned by doing. It worked great.
But at some point, I picked up a book because of a recommendation and it was astonishingly good (Cocoa Programming on OSX, Hillegaas). It gave me a real sense of confidence and overview that I was lacking in all my pull-learned topics. I guess this is because pull only ever provides very localized knowledge but you rarely see the big picture.
Since then, I tend to push-learn at first to get a feeling and overview over a language or framework and then gradually switch over to a more pull-oriented approach. This has served me very well. Some books out there are real marvels that can get you started with a new technology very painlessly. Gathering all that knowledge would take a lot longer. Yet, there is nothing as instructive as getting your own hands wet.
Interesting way to think about it. I found it funny because I've been working on ray tracing algorithms lately and it reminds me of that situation: They're both some form of optimization problems where you need to connect knowledge/light sources to problems/observers. Tracing from the knowledge/light source end is not efficient because you have no idea what will turn out to be important in the end, but tracing from the problem/observer end is also not efficient because in the end you have to connect your problem/observer to some knowledge/light source otherwise the entire path turned out to be futile.
Some form of bidirectional or multi-pass algorithm is likely to be more efficient here... ;-)
I take a "pull" approach myself, and you're absolutely right about him being in a good situation. A CS degree with no experience is more likely to get an ordinary programming job than a self-taught freelancer with 4 years experience under his belt - in my experience.
I just wanted to expand on the "find a job or project or someone who has a real need." This part was tricky for me. I love learning, and my approach for a long time was to just keep learning rather than doing. As soon as I would finish one programming book or tutorial series I'd start on another. If I ran across something new and interesting I would switch over to it. After a long time approach to doing that I realized I had a lot of half-baked knowledge and nothing to show for it.
Finally I buckled down and "did." I started by tackling a problem of my own - keeping focused, on task, and efficient. It has become a tangible project that I will (soon) be able to show a potential employer or even make money off of it. The best part is that it's something I personally believe in and need, so I'm passionate about it. Working on someone else's project sometimes makes it hard to get excited about what you're creating.
If you can't think of some problem of your own to solve, work on someone else's. The best approach I know of here is to find a local not-for-profit organization or charity. Ask them what could improve their ability to do whatever it is they do, or even help save them money and then create it. Give it to them free of charge. This a) gives you something tangible to show potential employers, b) could possibly be a tax write off, c) gives you real world "pull" experience, d) is for a good cause.
Some people might tell you that you should never do work for free. In this case, the work you're doing is benefiting you, even if there is no money involved. Besides, if it's for a good cause then there will be rewards - assuming you believe in God or karma :)
To reiterate edw519, adjust your attitude, find something to build, and do it.
I did a lot of Push learning in college and shortly afterward. I'd buy a bunch of books, read them cover to cover, and look up stuff on the web. I found that it was a good way to get familiar with certain topics, so I knew which tools to use for certain types of problems. The problem I found is that I'd spend lots of time reading about something that was less applicable, and the minute I got into a non-trivial application, I'd have to spend hours looking up details that I hadn't covered. I spent a bunch of time doing Push, but then had to also do an equal amount of Pull when I tried to use it.
I've since changed my approach. I limit my Push to little bits in order to familiarize myself with tools, but don't go too far in detail. This way I can cover a wider range of topics without wasting time on details I'll never use. Then when I actually start a project, I'll dive into the details as I'm using them. I find digging into details after you have context for what you're doing also helps with memory.
I think the OP probably learned more than they think they did, they just need some context to string it all together and help jog their memory. I wish I'd figured this out in college or shortly afterward, because most of what I learned was "in one ear, out the other".
I am a pull-learner as well. My physics undergrad and grad courses occasionally required that we program in Fortran, -that's what our profs used.
I once asked the head of our program why our degree didn't require any CS courses, but did require that we learn to code. She smiled and said "Well, we think you should just learn it." That short conversation made an impression on me. It wasn't in college study things, I was there to learn how to do things.
A good friend of mine is doing her second postdoc in physics. She does cosmology, and spends much of her time programming. For that reason, she has expressed a regret that she did not get much CS background in undergrad.
I find the attitude you expressed strange. They still insisted you take math courses, correct? Or did they say, "Well, we think you should just learn differential equations"?
I think it's a question of the kind of code that people do in science/engineering as compared to CS (my background is that I'm a practicing physicist, but started out with a background in Computer Engineering in undergrad.)
Yes, some basic CS (say an algorithms class) would be useful--but much of what we're working on as physicists is not what a traditional CS program would emphasize. For example, you have people with relatively small data sets that they want to fit--learning a language is about as far as they need to go. Others end up wanting to put a user interface around it if they use it excessively or distribute it for others. While perhaps a course on UI would be of use, for most, it's not what excites us, or advances us in our field.
Now, there are some who are doing high performance computing where abstraction and software engineering become important--but again, at the undergraduate level, how many courses are emphasizing the advantages of say templated C++ programming for scientific computations?
I think a service course on scientific computing would be of more use to most physicists than a general background in CS. For those that will end up working on large projects, then perhaps a course on software engineering. As for math courses, maybe I was a bit weird, but didn't you learn diff. equations in high school :p? But as for things like PDEs and such--I will say that a lot of it is learned as part of the coursework for say a first modern physics course, rather than in a math course...
For us, math, programming, etc. are tools that we use to do what we're interested in...(This is in no way to denigrate math or programming)
The head of the program was a cosmologist, actually. I know that she taught herself to code, as did the other two profs I worked for. -I think that had something to do with their attitudes. Also, it might have just been from a practicality standpoint. We didn't have the room for multiple CS courses, and the students seemed to be able to pick it up well enough to do what they needed to.
I have to mention, I did take a 100-level CS course as an elective, and personally, it was too basic. I think to get what we needed, we would have had to skip the intro courses, and I it's possible the CS department would have frowned on that. On a related note, my PhD was in medical physics, and our department did have an agreement with the bio department to let us take a 400 level physiology class without the prereqs. It was a point-of-pride in the physics program that our students always lead those classes.
No doubt CS can get deep and anyone that codes could benefit from those higher-level courses. But, I think the situation wouldn't allow for that.
Maybe she was saying that physics students were bright enough to figure out what they needed on their own. From what I saw, she would be correct there. We weren't math majors, but we were pretty able. :)
The problem with a pure pull approach is that you only know the first things that let you accomplish what you want to do. Sometimes, those first things are good enough to get the job done, but not enough to let you really know what's going on. That's not a problem now, but it may be in the future.
Anyway, it seems more like you agree CS courses aimed specifically at scientific computing would be good and worthwhile.
>Anyway, it seems more like you agree CS courses aimed specifically at scientific computing would be good and worthwhile.
Oh, absolutely. I think there might be an analogy in writing. -I'm no writer, but I can pen an effective grant. I'd really like to be an effective writer too, but that would be a divergent path in light of my work.
There's just not enough time in one human life. :/
BTW, a second postdoc is cruel and unusual punishment IMO. My best wishes to your friend.
Also, it's sad and unfair, but even though I've know some people succeed in getting a permanent position after the second postdoc, it gets harder as the number of postdoc increases...
As a physics undergrad we were told "you should probably learn a programming language", but were never given any specific course requirements (or suggestions that I remember).
I actually took multiple programming classes and ended up doing my PhD in computational physics. One of the biggest issues is that much of the software written by and for physicists tends to have very poor design, because they tend to learn the bare minimum necessary to get things to work (in Fortran no less).
They still insisted you take math courses, correct?
This is true, but we still learned a ton of math techniques in our physics classes. I must have learned Fourier transforms about 6 times (and finally understood them after the 3rd time or so :) )
I don't think that there is really this distinction, because your 'push' and 'pull' methods allow you to acquire different types of expertise/knowledge.
If you are all push, you won't be able to program.
If you are really all pull, you will be able to program, but it will be kind of magical programming.
Ex. If I am all pull: I know that the regular expression matches based on certain rules, but I don't understand complexity theory or finite automata, so I don't understand that I shouldn't use a regex to process xml. I might create a working program, but it is likely that it will be convoluted and take me longer (or be buggy in ways which I cannot comprehend!), because I reinvented solutions to already solved problems, or didn't understand the tools I was using.
If I am all push, programming becomes an intimidating experience. For obvious reasons, I'm going to have difficulty problem solving, obviously -- I've never actually sat down and solved problems. It would be like trying to learn math without having done any practice exercises.
I started as a 100% pull programmer (with minimal formal CS training), and have been pushing through a masters degree in CS. It has helped me by bounds. The concepts themselves are important, but also important is understanding the approach to problem solving that led to the concept. I can apply the theories behind a compiler or database (or anything) in places where a compiler or database would be totally inappropriate.
Point being, I see things differently now.
There are a lot more options for me to look into when I'm initially researching how to solve a problem, and it is a lot less likely to be influenced by whatever the new hotness buzzwords happen to be for the season, and because of that, my results are much better.
You bring up an interesting point - I was a "pull" programmer up until I went to university and took a Java course. I learnt there object oriented programming, and suddenly everything I had learnt previously "clicked" and I saw the big picture, and I'm a much better programmer for it.
You could make a comparison to music. The self-taught guitarist versus the classically trained guitarist, and the guitarist somewhere in between. When I took guitar lessons I wasn't taught classically, but I was taught the concepts (the theory behind chords, scales, etc.) and I was also encouraged to pick things up on my own by both playing around and finding tabs for my favourite songs and having a go.
This push vs pull concept can probably be applied to ways of learning in general. I think it's safe to say most people here are agreeing a mixture is best.
If you continue in the push environment long enough, you eventually have to start taking a pull approach - that's what research is. What's exciting about it is you have no choice but to use the pull approach - no one knows yet what the answers are, you need to figure them out.
Just remember all the algorithms and data structures they taught in class (the push stuff). That'll help you some day when you need to scale (while you're pulling).
Pull: You have a problem that you must solve, then you learn what you need, any way you can, to build the solution.
I call this "lazy evaluation", and it's my strongest learning style also.
When I set out to write a software synthesizer, for instance, I was reading papers and learning signal-processing stuff I wouldn't have otherwise bothered with.
Push: You learn from books, classes, mentors, and studying examples, then apply what you have learned.
Pull: You have a problem that you must solve, then you learn what you need, any way you can, to build the solution.
I suppose there are pros and cons of each method, and I imagine that many people here have used some of both.
For the record, I am 100% Pull. I have absolutely no formal training. It took me 2 years to find my first job and then I was thrown into the deep end. It was simultaneously frustrating and exhilarating. There were so many times I didn't know what to do or didn't have enough "tools" in my box. So I had to figure it out and find sources of learning. But I always did. Any when I got that first thing working and then saw my customer's eyes light up, I was hooked.
Your CS degree may make you think that you're a "push" learner, but may I suggest that you adopt a "pull" approach. Forget what you think you know and find a job or a project or someone who has a real need. Then build what you need. You a several advantages over me: (a) It shouldn't take you long to find that job/demand/customer. Just keep looking. (b) You already have tools in your tool box, maybe not the right ones for the job, but you have something. And (c) It's easier than ever to adopt a "pull" approach. Help is everywhere.
You may feel frustrated, but I don't think you have a problem at all. You're in a great (and very normal) situation. Just adjust you attitude, find something to build, and do it.