It's ok! I know how easy it is to do, but in this case I happened to remember other posters on SO recommending that the OP not use their full name as their nick, since the question might pop up in a pre-job-interview Google search.
That is how it is right now, but run into a brick wall until you conquer it isn't the best approach. Guided practice would be much better. For that to happen though we need to get better at being able to describe what we learned by running into that brick wall.
Similarly, I did not graduate with a CS degree, have been programming since 5th grade and yet feel I cannot program 'professionally' for a big firm that is loaded with CS geeks while I'm just an amateur programming for 13 years.
In this case, a lot of it is what you tell your brain.
Most hiring is based on the idea that it is far worse to employ a bad candidate than reject a good one - which favors an approach of choosing fairly arbitrary filters to whittle down the mountain of applications that any decent job has these days to a manageable quantity.
Requiring a degree is popular as it is an easy to implement filter rather than any correlation with ability. (Note that question of whether a CS degree is relevant or not is an other question entirely - I'm a CS graduate and I think the maths & theory heavy course I did is irrelevant to 98% of development jobs even if it has been pretty useful for me).
I'm a CS graduate and I think the maths & theory heavy course I did is irrelevant to 98% of development jobs even if it has been pretty useful for me
There are a few tidbits from your education that will save you from serious egg on your face. (See my other post this thread.) This is not just theoretical. I've seen a company suffer major embarrassment because software sold to Fortune 500 companies was written by programmers who thought, "all that poppycock about race conditions/transactions is just academic hot air."
Absolutely - the course I did in Concurrent Systems as part of my degree was of huge long term value because of the excellent set of mathematical abstractions it made be familiar with (Petri Nets and CSP in particular).
IMHO Computer Science courses deliver value through proving a knowledge of abstractions of software and hardware systems. These formal abstractions remain applicable pretty much forever whereas knowledge of particular technologies are of passing value.
[NB My hardwired knowledge of vi commands, Unix system calls and C was merely pleasant side effects of my CS degree not an end in itself]
I, myself, did not do computer science at university (I did civil engineering), and regret that a great deal. Not only does learning this stuff make you considerably more hire-able, it also enables solution of problems more sanely than a naive approach.
The real thing I feel that I miss is not being able to recognise where known algorithms/data structures could help out, something I'm working on fixing.
I've been thinking of doing a presentation: Everything I still actually use from my CS education in less than an hour. (It will take you a bit longer to study and really absorb, but it will probably take a lot less than 4 years of college and cost much less.)
EDIT: Another good thing to study, though I'm not sure if there's a good single source: Why distributed systems are Hard and why distributed transactions are Really Hard. I really didn't care for the teaching style of the professor who staked out that whole area as "turf" so none of my materials were particularly memorable or good, but the information was valuable.
The following are books from my student days. These are sources from which I happened to learn the "everything in an hour, but longer to absorb" subject matter. I'd recommend Applied Cryptography as excellent, the other is just good.
I cannot find my automata book just now. It's down in the garage, and I want to stay inside where it is warm now. As for concurrency, I got part of that from the Tannenbaum OS book:
But the rest, I actually got from a coworker on the job! We did cover databases and ACID transactions in school, but that wasn't taught very well and I didn't really get it until I was doing real work.
Do some assembly language. It will give you a key advantage over everyone who is too scared to touch it.
Write a compiler and/or interpreter. This can actually be pretty small, and it will also give you an advantage over those too scared of something so seemingly "esoteric."
It came out in, like, 1995 didn't it? I remember that because all my IRC friends immediately got to work on crazy crypto tools with algorithms and ideas cadged from that book. It definitely didn't teach them that crypto was hard.
I remember that because all my IRC friends immediately got to work on crazy crypto tools with algorithms and ideas cadged from that book. It definitely didn't teach them that crypto was hard.
It's one thing to do some fun project. It's another thing to do something for production. It's yet another thing to read such a book and realize it means there's people who know a lot more about this than you. At the same time, it is a fun read for a techie.
management didn't understand basic automata theory
Do tell more about it; as I feel that's not why they wasted millions.
IMHO management isn't required to understand much about CS, as long as the relationship with the developers is as between a customer and an engineer (i.e. customer asks for stuff, engineer explains what he can and cannot do).
Most problems with management comes from a disconnect with reality. Even when they know CS theory and/or could understand the complexity involved (ex developers); having bikeshed-style opinions and making demands with an iron fist in spite of developers advising otherwise (or the reverse, having developers on the team without an engineering mindset that can't think for themselves) ... that's the real poison.
management didn't understand basic automata theory
Do tell more about it; as I feel that's not why they wasted millions.
That company tried to translate code from one programming language to another using only regular expressions. (This was a long time ago when you couldn't almost count on most "regular expression" implementations being Turing Complete.)
Perhaps the problem was really that engineers who understood the futility of the approach didn't speak up or weren't listened to. Still, I'd expect people managing an engineering firm that builds bridges to have some basic grasp of physics. So I don't think it's going too far to have those running a software company to have some basic grasp of the basic laws governing their field.
I'm going to play devil's advocate here, and point out that you can actually construct the proper automaton where the transition conditions are decided by regular expressions.
It might work like this: some programmer working on the project realizes something can't be parsed in a finite state machine, and 'cleverly' separates out one batch of regular expressions into a loop/recursive call. Repeat until the programmers are satisfied with the number of conditions they can handle. I've seen software that was actually written like this. Fortunately, the language it was designed to parse was pretty simple.
I'm going to play devil's advocate here, and point out that you can actually construct the proper automaton where the transition conditions are decided by regular expressions.
It might work like this: some programmer working on the project realizes something can't be parsed in a finite state machine, and 'cleverly' separates out one batch of regular expressions into a loop/recursive call
In this case, you've created an "Augmented Transition Network" which is equivalent in power to a stack machine or a Context Free Grammar. Is this really playing devil's advocate? That would imply setting up something that isn't a straw man whose solution isn't basic automata theory.
This also gives you an idea of how broken the project was, since my understanding is that they'd fix "that particular bug" and keep writing more regular expressions.
The implication was that the project couldn't succeed because the management didn't understand basic automata theory, and insisted the programmers use only regular expressions. Presumably the regular expressions were being invoked by a Turing-complete programming language. Unless management decided that Turing-complete programming languages were not allowed, as well.
Amazing how often Turing-complete programming languages aren't utilized to their full potential. (And for the record, no I wasn't on that project. I have a CS degree and I remember automata.)
You can create a submachine representing the regular expression transition conditions, and just attach that at the state you wanted, resulting in a finite state machine.
Of course this doesn't hold when you are talking about non-standard regular expressions, and it's probably a nice feature to have when creating the automata, but IMHO it still sounds like a silly idea when CFG-tools like ANTLR and YACC are available.
Actually recursion in CS is equivalent to using a stack that keeps intermediate values and that grows in relation to the input.
If you've got an algorithm that does that, then it cannot be called "iterative".
I.e. backtracking is recursive, no matter how you implement it.
In school textbooks they do differentiate between "recursive" and "iterative" backtracking, to teach you how to get rid of the call-stack and manage your own. But that's another story.
I also hate working with ANTLR/YACC ... heavy, hard to start with, steep learning curve. These tools are designed for industrial-strength compilers, where performance / flexibility matters.
And PEGs are better than CFGs (that's teeshirt material right there :))
@stcredzero, that was exactly my point ... as a software developer I would never bend over and do as being told in that manner, because it is impossible to finish the task.
It wasn't just the management to be blamed: it the case of building bridges, engineers / architects can even go to prison if a bridge collapses.
"That company tried to translate code from one programming language to another using only regular expressions."
Ha! I know a guy who essentially got a US patent for roughly the same idea. His non technical bosses were so impressed that they gave him a raise and made him "Director of Analytics" at what was (or rather should have been) an Analytics heavy company.
If you really know how to program / software design / make it work, you can simply read "The New Turing Omnibus" (66 Excursions in Computer Science) from A.K. Dewdney and learn complexity/algorithms with "Introduction to Algorithms" from Cormen, Leiserson, Rivest and Stein. More important than _reading_ this last book is _doing_ the/some exercises, follow open course ware (for instance: http://ocw.mit.edu/courses/electrical-engineering-and-comput... ) if you prefer but do some exercises found in that book (or on Top Coder or Google Code Jam or whatever suits you).
Also, if you have time and passion, write a compiler.
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.
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 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.
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.
Push will allocate concepts into the logical recall section of your mind, meaning that you make the effort to recall these things. For instance, if I'm designing a UI, I'll sit back and think about principals and rules before I do anything.
Pull allocates into the creative regions, meaning you are a bit more intuitive towards what makes up good design.
One isn't always best for all stages of skill development towards mastering something, and a healthy development is likely to include both sides of effort. A push-and-pull if you will.
To draw an analogy, this is similar to language development in persons. Your native language is stored in the creativity hemisphere of your mind, and languages you are trying to pick up later in life are in the "information" side until they reach fluency. Cultural immersion would be a pull, where as learning from books is a push.
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... ;-)
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.
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).
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"?
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...
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)
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 :) )
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.
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.
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.
Chances are he did find a job in the last 8 months, but here's my input (maybe someone else in a similar situation can use it):
I graduated with a BS in ECE a few months ago, and also felt like I wasted 4 years for a piece of paper, but in those 4 years, I gained a lot of web development experience. While interviewing for the next few months after graduation, I saw that I knew a lot more about web development than EE, and that I was more interested in web development and CS. I landed a programming job where I'm learning more than I've learned during four years of electrical engineering courses.
So my advice is to find what you're more interested in, and maybe you have college work or extra-curricular experience that can help. Engineering and CS share a similar thought process, and employers look for this in their technical interviews - especially if they know you don't come from a formal CS education.
As others have pointed out, you can (and should) work on personal projects and freelance. Besides helping you learn and gain experience, you might even make some money!
I learned extremely few industry-applicable skills in a prestigious CS undergrad program. Instead, I picked up 99% of my useful knowledge from a few other places:
- One semester-long software development class, where the teacher did literally nothing while we formed small teams and worked on a project for a real client in or near our university
- Software engineering internship in the industry
- Extremely hard-ass Advanced Placement C.S. teacher in high-school
I learned a lot of cool theoretical stuff in college that is definitely good to know: functional programming, operating systems, machine learning techniques, compilers, graph algorithms, etc., but was never taught any core programming techniques or required to write very extensive code at any level of quality. It's all about real-world experience, if that's what you're shooting for.
Sounds like a case of mishandled expectation to me. Computer science is a mathematical and logical discipline; programming is a good means to practice that mathematics and logic, but it's not what computer science is.
I remember feeling the same thing in college... I expected CS to be a vocational program that would teach me how to write the applications I used on Windows every day. By Senior year, when not a single "real world" application was written, I finally realized it was all about teaching good theory and practice, and the practical stuff I'd need to pick up on my own.
Several students in my campus ACM chapter realized this and worked to make our meetings fill in some of the gaps. We had weekly meetings and covered things that attendees could get started using immediately. Code-alongs were encouraged. Popular topics had followup meetings. I don't even know how much time we spent playing with POV-Ray.
The lightning talks meeting was also really popular; one guy showed how to use Blender in five minutes, someone else talked about a darknet he had written, and another student used it to distribute Google Wave invites she had from her summer internship.
The reality is that no one knows how to do any professional job when they graduate from college. What we learn in college is mostly how to learn and how to problem solve. The problems we solve in college, whether stumbling through our first sorting algorithms or writing a paper about the role of Prussian nationalism in the 1800s, are not tied at all to the problems we have to solve professionally. And that's okay.
When it comes to being a practitioner, whether producing commercial software products or writing analyst reports on public companies, the job itself is the best training. What you have to bring to the table is the curiousity and ability to learn and problem solve that get you up the learning curve quickly, and the professionalism that makes you a reliable and welcome colleague.
This sentiment is true, I think, for any profession, graduating with an undergraduate degree just gets the door open, you still have a long way to walk. Similarly, if you're an English major reading The New Yorker, you may not feel like you know how to write a decent piece.
This is a philosophical question about whether a CS degree should be educational or vocational. The general consensus seems to be that it should be the former not the latter. It should give you the theoretical foundation that you can apply to almost anything.
Therefore, college won't necessarily teach you any programming beyond what you need to read examples and do assignments, which may not be particularly deep.
2. Do you like to program?
Frankly, every good programmer I know started programming long before they went to college or at least programmed outside of college for their enjoyment.
If you haven't done that and don't do that then I really have to question if you're in the right profession.
3. Programming vs Being a Programmer.
Being a programmer as a job for which you are paid is different to programming. It involves many other skills such as design, reviews, dealing with people, writing documentation, supporting applications and so on. This is not something taught in school (nor could it be really).
I view the first 2-3 years of your work life as an apprenticeship of sorts. You've got the basic theory, now you have to go out into the real world and make yourself useful to somebody.
Many companies have graduate programs and the like. I think it's fairly important to start off somewhere that's good, meaning they'll teach you something (rather than simply crushing you, which, sadly, is more the norm).
If you can put in 2-3 years at, say, Google, Facebook or Apple after doing a good CS course, you'll have gotten yourself off to a very good start.
The "do you like to program" and "programming vs. being a programmer" are really good points.
We recently hired and then let go of a guy who is doing a CS degree, good grades, competes in ACM tournaments, so he was really sexy as a junior programmer. It turned out he doesn't really like to program, he's not a programmer. The way this materialized was when given an assignment, he wasn't willing to proactively figure out how to solve it. We either told him in great detail how to solve it or he'd throw up his arms.
This happened in 9 out of 10 cases, whether it was a really small (1 hour) or a larger (multi-month) assignment. After two months of this we let him go.
1. Should college teach you to program?
This is a philosophical question about whether a CS degree should be educational or vocational. The general consensus seems to be that it should be the former not the latter. It should give you the theoretical foundation that you can apply to almost anything.
Therefore, college won't necessarily teach you any programming beyond what you need to read examples and do assignments, which may not be particularly deep.
I personally think that's a problem. There is nothing wrong with being educational in your sense of the term, but I do think people with a degree in CS should be expected to know how to program.
Not expecting a CS alumnus to be a programmer is like having an architect not know how to draw buildings, or a surgeon not know how to wield a scalpel.
Sure, the degree should absolutely teach you more than just programming, but there is no value in being a CS grad without knowing how to program. It's sort of the low level toolkit that you absolutely must be proficient in to being with.
A strange thing about CS education is that we have all these people studying Computer Science or even Software Engineering without ever looking at a significant piece of software. You learns lots of small examples and lots of theoretical bits, but as far as I can see most programs never take a look at, say, the Apache webserver and explain how all these small things come together to produce a successful piece of software. That's really a pity.
Not expecting a CS alumnus to be a programmer is like having an architect not know how to draw buildings, or a surgeon not know how to wield a scalpel.
You do realize that with both professions you noted there is usually an apprenticeship time (internship/residency) -- and also in both professions you must licensed (in architecture typically after your internship and in medicine before the residency).
I do disagree though that there is no value in not being able to program. The main contribution of CS is not programming. It is in the theory of computation. I really do view programming as purely incidental.
You wouldn't expect a mechanical engineer to know how to repair a 2011 Ford Focus. They'll konw the basic ideas under the hood, but all of the technoogy specific aspects of it shouldn't be taught.
What you want is a different program. Call it software engineering. I agree that too many people seek CS degrees, but that is not a good reason to change CS into something that it is not.
"Frankly, every good programmer I know started programming long before they went to college or at least programmed outside of college for their enjoyment.
If you haven't done that and don't do that then I really have to question if you're in the right profession."
Do you apply those standards to everyone, or just to programmers? If only programmers, why?
Same goes for other more common disciplines too, especially the engineering disciplines. How many people were building bridges, designing buildings, or creating CPUs before their formal education?
The engineering-ish side of CS (programming) is far more similar to the sciences (physics, chemistry) or mathematics than other engineering disciplines are because anyone with drive can and does delve into it without the help/permission of formal educators.
This is to say nothing of the fact that real CS is a branch of mathematics...
However, there are others in the same vein as programming:
* fine arts (drawing, painting)
* music
* football and other sports
* creative writing
I'd guess that any student majoring in the above fields already possessed basic (or even advanced) skills before entering the university.
On the other side, there are fields that are more "professional", where students only begin learning these disciplines at college:
* medicine
* psychology
* economics
* law
Obviously, students are exposed to concepts before college, but they wait until they get the professional credential before doing surgery, filing lawsuits, prescribing antidepressants, or raising interest rates.
"Frankly, every good programmer I know started programming long before they went to college or at least programmed outside of college for their enjoyment.
If you haven't done that and don't do that then I really have to question if you're in the right profession."
This scared me in college, since I hardly programmed before (or even during) my degree. However, I've found that it's simply not true. Not just for myself, but for the many people I've met who started with completely different careers before getting into programming.
Everyone you know knew how to program before college?
Just curious:
A. Were you born after 1990?
B. Is nobody you know from even a slightly disadvantaged background?
I got into programming partly because I didn't have a lot of money. My parents were smart enough to recognize that having at least one computer in the household was incredibly important, but that one computer happened to be a good decade out of date. One of those "I saw this at a yardsale and picked it up for $50s" deals", the type of machine I use as personal mailservers/spaceheaters these days... I sure couldn't game on it, so besides using it for word processing and research, I learned how to program on it. I grew sick of win95, and nothing else would run on it, so I learned how to put linux on it and use that.
Anyway, my point is this: My current machine I do most of my work on has 64 GB of ram and 32 cores, but you absolutely can get into computing with the kind of money you can earn on a weekend mowing lawns.
(And yes, I was born before 1990. Not everyone in college knew how to program already, but all the kids who made it through the weedout courses sure did...)
Well, good stuff. :) I didn't have access to a pc before uni (1998); I just ate the material up and practically memorised Deitel & Deitel's c++. I worked for so little cash programming through summer I suffered from malnutrition. I don't even know if I was natural - I just banged my head against the wall until it fell down. It really is rather rewarding :D.
I lived in BFE, Idaho until college and didn't have access to a PC most of my time there, and unfortunately, I had access to zero programmers. My introduction to programming concepts was made through trying to figure out and modify crappy JavaScript snippets on websites in 1999 over a 33.6K connection.
When I entered college, I was surprised that most of my classmates have had broadband connections and better computers for years, but never bothered to do much more than receive email with them.
Being an undergraduate in a large public university gives you all sorts of great opportunities, like rooming with a painter (art studio/anthro double major). Among the many jewels I've borrowed from our conversations, one I particularly treasure is the notion of praxis.
Praxis (as I understand it) is simply the harmonious blending of practice and theory into action. As I'm beginning the exit trajectory from undergrad and into the "real world" (whatever that is), I've been reflecting on my education in the art of programming. I've realized that praxis has been the only substantial educational tool I've had.
Knuth says it best. “If you find that you're spending almost all your time on theory, start turning some attention to practical things; it will improve your theories. If you find that you're spending almost all your time on practice, start turning some attention to theoretical things; it will improve your practice.”
I respect your opinion, however I'm quite sure that person who asked this question actually cares about what he does because I don't think he would have posted this otherwise. I mean I could be wrong but this is what I felt when I read it.
Either he just doesn't have the natural aptitude, or he doesn't love it enough to learn.
I can't fathom how anyone could be a programmer/trying to become a programmer and not have constant side projects, partially written OSes, games, etc
It's easy to say "I want to be an X", but then you realize that you're not spending enough time doing X to become good at it. And the reason you're not spending enough time doing it is because you just don't love it enough, perhaps you love something else more.
He writes "I'm trying to improve my knowledge by studying algorithms, but it is a long and painful process."
Which is depressing. You do not learn how to program by 'studying algorithms'.
Do you learn to become a great author by reading the dictionary? No.
It doesn't sound like he wants to be a programmer for the right reasons to me.
The (quite old; it'd be interesting to see how this panned out) question came across to me as someone who, at the end of their many years in education up to this point, has got very used to directed learning. They are used to learning by being set a challenge with some accompanying theory and completing the challenge. They may well be good at this and enjoy doing it, but they haven't become used to searching out the material for themselves.
In fairness, for a corporate setting this may not be a great limitation! When you're working on someone else's project doing maintenance work as most developers end up doing, the need to seek out new problems and work out novel methods can come later; for now, your work domain is fairly closely controlled.
We may well have a CS graduate without the passion to stick at development, but this isn't necessarily the case. I did very little personal work then, because I had other interests as well and was doing plenty of programming for my course, thank you. I think we've got someone with the self-awareness to realise their limitations but insufficient experience of learning outside of education to know how to address this.
It came across to me as someone who wants to learn programming for the wrong reasons. For example they heard it pays well. Rather than wanting to learn it because they love it.
I think there is huge value in trying to become what has been called a "full stack programmer". In the maning of: try to understand how computer systems work by understanding how each part of the stack works. Don't try to completely understand every subtle detail of every part - try to understand it like you understand how a combustion engine works.
My list would be:
- basic electronic concepts, ie. transistors, XOR / NAND, bit shifters, adders
- assembly language
- hardware layout: CPU, registers, main memory, MMU, interrupts
- operating systems: hardware interface, multi processing, file systems
- networking: packet networks, ethernet, TCP/IP (sliding window, congestion control)
- low level programming: C with fopen & co, sockets, structs, system calls
- compiler construction (this is important!), parsers, translators, programming language implementation and virtual machines
- algorithms: complexity theory, automata, CFGs, common data structures (heaps, maps, trees)
- discrete mathematics, statistics
I think if you can explain all of these in at least a sort-of, hand wavy way, then you're on a good path to become an excellent programmer. I also think that is what a good CS degree should teach you. Try to explain to yourself in a children's story way what actually happens when you click your mouse button. If you don't know something, look it up.
Who has the time? And you can be employable knowing only 1 of those.
I've done that stuff; by necessity, I'm old enough to have grown up with computers and didn't have it all on a platter. My sons are learning "top down" and doing fine.
Pretty much I think this is one reason why the big names in software industry did not totally adopt the notion of graduating with a degree. What they did was to venture out on the real world and try solving some problems that they have by using computers and understanding how to program it. Pretty much I think it is safe today that 90% (or more) of what's being taught in universities offering CS degrees doesn't match up with what's happening in the real world. You want to program, sit on a computer, find something to solve and do it.
Myself (and many colleagues) are professional EE's. We all own soldering irons and know how to solder in the most basic sense (I'm one of the few with a hot-air rework station and a stereo microscope).
About half of the professional ME's I know either own a TIG/MIG welding system and/or know how to weld.
imho, cs degrees are not supposed to be about programming. their focus should be purely theoretical side of computation e.g. heavy emphasis on algorithms, data structures etc. etc. which pushes them mostly towards applied mathematics imho. most programmers are autodidacts anyways, and picking stuff up is generally not that hard.
How refreshing. When I graduated I thought I knew it all.
"I see websites like Stack Overflow and search engines like Google and don't know where I'd even begin to write something like that."
In response I'll quote part of the best paragraph PG's ever written:
"I've always been fascinated by comb-overs, especially the extreme sort that make a man look as if he's wearing a beret made of his own hair. How does the comber-over not see how odd he looks? The answer is that he got to look that way incrementally. What began as combing his hair a little carefully over a thin patch has gradually, over 20 years, grown into a monstrosity. Gradualness is very powerful. And that power can be used for constructive purposes too: just as you can trick yourself into looking like a freak, you can trick yourself into creating something so grand that you would never have dared to plan such a thing. Indeed, this is just how most good software gets created. You start by writing a stripped-down kernel (how hard can it be?) and gradually it grows into a complete operating system." -- http://paulgraham.com/essay.html (His best essay IMO.)
134 comments
[ 2.8 ms ] story [ 210 ms ] threadThe college will teach you the basic, it will give you a ground to know how to start building. They won't tell you how to put the bricks together.
That's why I help my co-workes with something they don't know and encourage them to do the same with others.
Learning how to recover and navigate gracefully around the brick walls will serve you well in the real world.
In this case, a lot of it is what you tell your brain.
Requiring a degree is popular as it is an easy to implement filter rather than any correlation with ability. (Note that question of whether a CS degree is relevant or not is an other question entirely - I'm a CS graduate and I think the maths & theory heavy course I did is irrelevant to 98% of development jobs even if it has been pretty useful for me).
There are a few tidbits from your education that will save you from serious egg on your face. (See my other post this thread.) This is not just theoretical. I've seen a company suffer major embarrassment because software sold to Fortune 500 companies was written by programmers who thought, "all that poppycock about race conditions/transactions is just academic hot air."
IMHO Computer Science courses deliver value through proving a knowledge of abstractions of software and hardware systems. These formal abstractions remain applicable pretty much forever whereas knowledge of particular technologies are of passing value.
[NB My hardwired knowledge of vi commands, Unix system calls and C was merely pleasant side effects of my CS degree not an end in itself]
The real thing I feel that I miss is not being able to recognise where known algorithms/data structures could help out, something I'm working on fixing.
I've actually worked at a company that wasted millions on a fruitless project because management didn't understand basic automata theory:
I've been thinking of doing a presentation: Everything I still actually use from my CS education in less than an hour. (It will take you a bit longer to study and really absorb, but it will probably take a lot less than 4 years of college and cost much less.)EDIT: Another good thing to study, though I'm not sure if there's a good single source: Why distributed systems are Hard and why distributed transactions are Really Hard. I really didn't care for the teaching style of the professor who staked out that whole area as "turf" so none of my materials were particularly memorable or good, but the information was valuable.
Algorithms: Introduction to Algorithms (Cormen, Leiserson, & Rivest) http://amzn.com/0262033844
Security: Applied Cryptography (Schneier) http://amzn.com/0471117099
I cannot find my automata book just now. It's down in the garage, and I want to stay inside where it is warm now. As for concurrency, I got part of that from the Tannenbaum OS book:
http://amzn.com/0131429388
But the rest, I actually got from a coworker on the job! We did cover databases and ACID transactions in school, but that wasn't taught very well and I didn't really get it until I was doing real work.
Do some assembly language. It will give you a key advantage over everyone who is too scared to touch it.
Write a compiler and/or interpreter. This can actually be pretty small, and it will also give you an advantage over those too scared of something so seemingly "esoteric."
http://news.ycombinator.com/item?id=639786
Thomas recommends Practical Cryptography instead.
"Practical" will be my next technical read.
That would be about right.
I remember that because all my IRC friends immediately got to work on crazy crypto tools with algorithms and ideas cadged from that book. It definitely didn't teach them that crypto was hard.
It's one thing to do some fun project. It's another thing to do something for production. It's yet another thing to read such a book and realize it means there's people who know a lot more about this than you. At the same time, it is a fun read for a techie.
IMHO management isn't required to understand much about CS, as long as the relationship with the developers is as between a customer and an engineer (i.e. customer asks for stuff, engineer explains what he can and cannot do).
Most problems with management comes from a disconnect with reality. Even when they know CS theory and/or could understand the complexity involved (ex developers); having bikeshed-style opinions and making demands with an iron fist in spite of developers advising otherwise (or the reverse, having developers on the team without an engineering mindset that can't think for themselves) ... that's the real poison.
That company tried to translate code from one programming language to another using only regular expressions. (This was a long time ago when you couldn't almost count on most "regular expression" implementations being Turing Complete.)
Perhaps the problem was really that engineers who understood the futility of the approach didn't speak up or weren't listened to. Still, I'd expect people managing an engineering firm that builds bridges to have some basic grasp of physics. So I don't think it's going too far to have those running a software company to have some basic grasp of the basic laws governing their field.
It might work like this: some programmer working on the project realizes something can't be parsed in a finite state machine, and 'cleverly' separates out one batch of regular expressions into a loop/recursive call. Repeat until the programmers are satisfied with the number of conditions they can handle. I've seen software that was actually written like this. Fortunately, the language it was designed to parse was pretty simple.
It might work like this: some programmer working on the project realizes something can't be parsed in a finite state machine, and 'cleverly' separates out one batch of regular expressions into a loop/recursive call
In this case, you've created an "Augmented Transition Network" which is equivalent in power to a stack machine or a Context Free Grammar. Is this really playing devil's advocate? That would imply setting up something that isn't a straw man whose solution isn't basic automata theory.
This also gives you an idea of how broken the project was, since my understanding is that they'd fix "that particular bug" and keep writing more regular expressions.
You can create a submachine representing the regular expression transition conditions, and just attach that at the state you wanted, resulting in a finite state machine.
Of course this doesn't hold when you are talking about non-standard regular expressions, and it's probably a nice feature to have when creating the automata, but IMHO it still sounds like a silly idea when CFG-tools like ANTLR and YACC are available.
The key is the bit about the "recursive call."
If you've got an algorithm that does that, then it cannot be called "iterative".
I.e. backtracking is recursive, no matter how you implement it.
In school textbooks they do differentiate between "recursive" and "iterative" backtracking, to teach you how to get rid of the call-stack and manage your own. But that's another story.
I also hate working with ANTLR/YACC ... heavy, hard to start with, steep learning curve. These tools are designed for industrial-strength compilers, where performance / flexibility matters.
And PEGs are better than CFGs (that's teeshirt material right there :))
It wasn't just the management to be blamed: it the case of building bridges, engineers / architects can even go to prison if a bridge collapses.
Ha! I know a guy who essentially got a US patent for roughly the same idea. His non technical bosses were so impressed that they gave him a raise and made him "Director of Analytics" at what was (or rather should have been) an Analytics heavy company.
That will be really helpful. Thanks.
Also, if you have time and passion, write a compiler.
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.
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 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.
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.
Pull allocates into the creative regions, meaning you are a bit more intuitive towards what makes up good design.
One isn't always best for all stages of skill development towards mastering something, and a healthy development is likely to include both sides of effort. A push-and-pull if you will.
To draw an analogy, this is similar to language development in persons. Your native language is stored in the creativity hemisphere of your mind, and languages you are trying to pick up later in life are in the "information" side until they reach fluency. Cultural immersion would be a pull, where as learning from books is a push.
This is a great way to describe these different ways of learning. I'll be using these terms again. Thanks.
Some form of bidirectional or multi-pass algorithm is likely to be more efficient here... ;-)
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.
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 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.
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 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. :)
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.
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)
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 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.
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 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.
- One semester-long software development class, where the teacher did literally nothing while we formed small teams and worked on a project for a real client in or near our university
- Software engineering internship in the industry
- Extremely hard-ass Advanced Placement C.S. teacher in high-school
I learned a lot of cool theoretical stuff in college that is definitely good to know: functional programming, operating systems, machine learning techniques, compilers, graph algorithms, etc., but was never taught any core programming techniques or required to write very extensive code at any level of quality. It's all about real-world experience, if that's what you're shooting for.
The lightning talks meeting was also really popular; one guy showed how to use Blender in five minutes, someone else talked about a darknet he had written, and another student used it to distribute Google Wave invites she had from her summer internship.
If this is so, and you can't program, then how did they appear?
1. Should college teach you to program?
This is a philosophical question about whether a CS degree should be educational or vocational. The general consensus seems to be that it should be the former not the latter. It should give you the theoretical foundation that you can apply to almost anything.
Therefore, college won't necessarily teach you any programming beyond what you need to read examples and do assignments, which may not be particularly deep.
2. Do you like to program?
Frankly, every good programmer I know started programming long before they went to college or at least programmed outside of college for their enjoyment.
If you haven't done that and don't do that then I really have to question if you're in the right profession.
3. Programming vs Being a Programmer.
Being a programmer as a job for which you are paid is different to programming. It involves many other skills such as design, reviews, dealing with people, writing documentation, supporting applications and so on. This is not something taught in school (nor could it be really).
I view the first 2-3 years of your work life as an apprenticeship of sorts. You've got the basic theory, now you have to go out into the real world and make yourself useful to somebody.
Many companies have graduate programs and the like. I think it's fairly important to start off somewhere that's good, meaning they'll teach you something (rather than simply crushing you, which, sadly, is more the norm).
If you can put in 2-3 years at, say, Google, Facebook or Apple after doing a good CS course, you'll have gotten yourself off to a very good start.
We recently hired and then let go of a guy who is doing a CS degree, good grades, competes in ACM tournaments, so he was really sexy as a junior programmer. It turned out he doesn't really like to program, he's not a programmer. The way this materialized was when given an assignment, he wasn't willing to proactively figure out how to solve it. We either told him in great detail how to solve it or he'd throw up his arms.
This happened in 9 out of 10 cases, whether it was a really small (1 hour) or a larger (multi-month) assignment. After two months of this we let him go.
I personally think that's a problem. There is nothing wrong with being educational in your sense of the term, but I do think people with a degree in CS should be expected to know how to program.
Not expecting a CS alumnus to be a programmer is like having an architect not know how to draw buildings, or a surgeon not know how to wield a scalpel.
Sure, the degree should absolutely teach you more than just programming, but there is no value in being a CS grad without knowing how to program. It's sort of the low level toolkit that you absolutely must be proficient in to being with.
A strange thing about CS education is that we have all these people studying Computer Science or even Software Engineering without ever looking at a significant piece of software. You learns lots of small examples and lots of theoretical bits, but as far as I can see most programs never take a look at, say, the Apache webserver and explain how all these small things come together to produce a successful piece of software. That's really a pity.
You do realize that with both professions you noted there is usually an apprenticeship time (internship/residency) -- and also in both professions you must licensed (in architecture typically after your internship and in medicine before the residency).
I do disagree though that there is no value in not being able to program. The main contribution of CS is not programming. It is in the theory of computation. I really do view programming as purely incidental.
You wouldn't expect a mechanical engineer to know how to repair a 2011 Ford Focus. They'll konw the basic ideas under the hood, but all of the technoogy specific aspects of it shouldn't be taught.
Do you apply those standards to everyone, or just to programmers? If only programmers, why?
The engineering-ish side of CS (programming) is far more similar to the sciences (physics, chemistry) or mathematics than other engineering disciplines are because anyone with drive can and does delve into it without the help/permission of formal educators.
This is to say nothing of the fact that real CS is a branch of mathematics...
However, there are others in the same vein as programming:
I'd guess that any student majoring in the above fields already possessed basic (or even advanced) skills before entering the university.On the other side, there are fields that are more "professional", where students only begin learning these disciplines at college:
Obviously, students are exposed to concepts before college, but they wait until they get the professional credential before doing surgery, filing lawsuits, prescribing antidepressants, or raising interest rates.This scared me in college, since I hardly programmed before (or even during) my degree. However, I've found that it's simply not true. Not just for myself, but for the many people I've met who started with completely different careers before getting into programming.
Anyway, my point is this: My current machine I do most of my work on has 64 GB of ram and 32 cores, but you absolutely can get into computing with the kind of money you can earn on a weekend mowing lawns.
(And yes, I was born before 1990. Not everyone in college knew how to program already, but all the kids who made it through the weedout courses sure did...)
When I entered college, I was surprised that most of my classmates have had broadband connections and better computers for years, but never bothered to do much more than receive email with them.
Praxis (as I understand it) is simply the harmonious blending of practice and theory into action. As I'm beginning the exit trajectory from undergrad and into the "real world" (whatever that is), I've been reflecting on my education in the art of programming. I've realized that praxis has been the only substantial educational tool I've had.
Knuth says it best. “If you find that you're spending almost all your time on theory, start turning some attention to practical things; it will improve your theories. If you find that you're spending almost all your time on practice, start turning some attention to theoretical things; it will improve your practice.”
This is why there are so many bad programmers around. Depressing.
I can't fathom how anyone could be a programmer/trying to become a programmer and not have constant side projects, partially written OSes, games, etc
It's easy to say "I want to be an X", but then you realize that you're not spending enough time doing X to become good at it. And the reason you're not spending enough time doing it is because you just don't love it enough, perhaps you love something else more.
He writes "I'm trying to improve my knowledge by studying algorithms, but it is a long and painful process."
Which is depressing. You do not learn how to program by 'studying algorithms'.
Do you learn to become a great author by reading the dictionary? No.
It doesn't sound like he wants to be a programmer for the right reasons to me.
The (quite old; it'd be interesting to see how this panned out) question came across to me as someone who, at the end of their many years in education up to this point, has got very used to directed learning. They are used to learning by being set a challenge with some accompanying theory and completing the challenge. They may well be good at this and enjoy doing it, but they haven't become used to searching out the material for themselves.
In fairness, for a corporate setting this may not be a great limitation! When you're working on someone else's project doing maintenance work as most developers end up doing, the need to seek out new problems and work out novel methods can come later; for now, your work domain is fairly closely controlled.
We may well have a CS graduate without the passion to stick at development, but this isn't necessarily the case. I did very little personal work then, because I had other interests as well and was doing plenty of programming for my course, thank you. I think we've got someone with the self-awareness to realise their limitations but insufficient experience of learning outside of education to know how to address this.
My list would be:
I think if you can explain all of these in at least a sort-of, hand wavy way, then you're on a good path to become an excellent programmer. I also think that is what a good CS degree should teach you. Try to explain to yourself in a children's story way what actually happens when you click your mouse button. If you don't know something, look it up.I've done that stuff; by necessity, I'm old enough to have grown up with computers and didn't have it all on a platter. My sons are learning "top down" and doing fine.
Of course, most places I've dealt with have no desire to hire someone who is a generalist: specialist or get out is my observation.
I'm graduating with a ME degree but I don't feel like I know how to weld.
About half of the professional ME's I know either own a TIG/MIG welding system and/or know how to weld.
Becoming a good programmer is something different.
() Deconstructing problems into smaller problems and expressing those in computer commands.
A worthless piece of paper. Had a fun three years getting it though.
Or maybe I just never get any better, hm.
"I see websites like Stack Overflow and search engines like Google and don't know where I'd even begin to write something like that."
In response I'll quote part of the best paragraph PG's ever written:
"I've always been fascinated by comb-overs, especially the extreme sort that make a man look as if he's wearing a beret made of his own hair. How does the comber-over not see how odd he looks? The answer is that he got to look that way incrementally. What began as combing his hair a little carefully over a thin patch has gradually, over 20 years, grown into a monstrosity. Gradualness is very powerful. And that power can be used for constructive purposes too: just as you can trick yourself into looking like a freak, you can trick yourself into creating something so grand that you would never have dared to plan such a thing. Indeed, this is just how most good software gets created. You start by writing a stripped-down kernel (how hard can it be?) and gradually it grows into a complete operating system." -- http://paulgraham.com/essay.html (His best essay IMO.)