More Ramblings from a Los Angeles Programmer

January 27, 2008

Schools and that jazz

Filed under: coding, technology — Tags: , , , , , , — Josh DeWald @ 7:31 pm

There has been a lot of furor (at least from all the links popping up on proggit) around the “worth” of CS degrees and how bad the programs are.

My personal take is that people are expecting the wrong thing out of it. There is certainly a mechanical/trade aspect to programming. That’s the part that they can teach quite well: syntax, basic algorithms, etc. Strangely, this is the part they only teach in Software “Engineering” courses versus pure “Computer Science.” Most people go into these programs expecting to be able to walk into a typical business programming job and get to work. They really do no want to learn about Big O, Finite State Machines, or Data Structure Implementation. Who wants to know about all that damn math!?

The bit that they do not teach well is the part that actually makes you good at “programming”: critical thinking problem solving skills. Much of your time is spent figuring out how to go from problem to solution and, after doing that, why the apparent solution does not actually solve the problem correctly. You will spend a lot of time debugging software and fixing bugs. That’s just the way it is. Yes, each language makes some aspect of expression easier, but at the end of the day the actual algorithm is exactly the same. There are really only two ways a bit of program can be wrong:

  1. The algorithm is incorrect
  2. The expression of the algorithm is incorrect

I would argue that the analysis of either of these problems requires slightly different skills. One of them is the heart of “computer science” and it is the creation of algorithms that solve problems in faster and more innovative ways that are researched. The majority of us will never come up with a truly new algorithm; rather we will solve a problem that is just being defined in terms of different nouns. So a key skill of any programmer (during the design phase of construction, however short that may be) is recognizing how the problem can be re-phrased in another light and use a known algorithm. The site TopCoder is an excellent way to practice this.

Assuming that the proper algorithm has been chosen, the next step is to actually implement it. Theoretically this is the “easy” part, but it is also where the majority of effort is placed in the real world. An absolutely necessary skill of a software engineer is to be able to follow the logic of code (usually people speak of reading code but I really think you follow the logic of code instead. While I have seen some poetic code before, it really isn’t literary in nature) and trace what it is doing with a particular input. It is this skill (or the lack of) which is why, i believe, people complain about bad Computer Science education. You can whine and moan about Java or C++ being used (instead of “pure” languages like Haskell) but frankly that is a bunch of hogwash. If a person is getting the right education, or has the right innate talent, then they will be able to solve problems in any language given to them.

I have always said to people that one of the most useful classes I ever had in college was my Physics class. The professor was smart and did not allow calculators on the exams. You see, it is not the answer that matters, but how you get there. Your algorithm. The most important lessons in Computer Science (and medicine, and law, and….) is those that teach critical thinking and being methodical about solving a problem.

Ruby will not make you magically a better programmer. Java does not turn you into some brainless idiot. Perl will not turn you into a person incapable of writing clear code. Using RAD tools will not prevent you from learning how your code actually works. It is the person behind the code that matters.

Update: I found this response to the debate by Brian Hurt at Enfranchised Mind to be very good (and much better written than mine) in the sense of mentioning that, effectively, you want a “Developer that knows Java” rather than a “Java Developer”.  The reality, though, even if we don’t want to admit it, is that companies want Java developers. What do they care if the person will be useless 10 or 20 years from now, they’ll just get a developers that are trained up on New Fangled Language X.

November 27, 2007

Architecture and Coding

Filed under: coding, technology — Tags: , , , — Josh DeWald @ 8:49 pm

I have the word “architect” in my title at work, which is cool cause it apparently means I know what I am doing but is bad because it means that people assume that I always know what I am doing.

I consider myself a pretty good software engineer, in that I can generally produce working software against the requirements given to me. I actually do not tend to be up on the latest trends in WS-* or frameworks, etc so most of my code is pretty straightforward (I hope). Thankfully others I work with (both at work and on hobby stuff) keep up with things like Hibernate, Spring, Quartz so it allows me to keep track of what people are actually using, versus what the hype is. I will shamelessly take the skeletons of how those systems are used by other co-workers and friends. However, I always try to figure out how to make using them easier if I find bits that are in any way non-intuitive.

I tend to write in an “agile” way. What this really means is that I think about the problem and do some drawings, pseudocode, sketches, pictures, whatever that I need to get something up and running that solves an immediate problem. Then I move on to other components. Realize that I missed a detail. Rinse. Repeat As I move onto other requirements I integrate them with my solution and always try to have a working system that does something.

Back to the point of my story… this is a horrible way to work if you are supposed to “architect” (in the sense of “here is the design, build it”) a system based on a set of requirements. It is very easy to draw some lines and boxes with cool names and leave the “details as an exercise for the programmer.” Bad idea. By the time it has made it to the programmer (unless they work intimately with you on your own team) many of the requirements have been lost, and they are left only with the design. So they implement, or try to implement, what has been given to them. And surprise, surprise, it meets the requirements but does not actually work.

This is when I realize that what I really gave was a design for a “first pass” that would really be a prototype of the system. If I were implementing, it would be easy to turn around and enhance to go to the next level. But in this case, it has already gone down through two other levels of tech lead and off-shore architect. So not very easy to say “ok, so that we aren’t quite there yet, we actually have a million other details to work out”.

So lesson learned there is that however long you would normally give yourself to “design” the system, multiply it by 10 so that you can basically look at every single API and external system being called, and run through every use case you can think of to see if the design does in fact meet the requirements and produce a working system. It really is not enough to see that API X has a method that looks like Y and takes parameters A and B and probably does Z. What happens if you have 1 million sets of {A,B}?

My real point, I suppose, is that being fairly good at designing and implementing your own systems does not make you an architect. And if you are in that position, do not let someone tell you that you only need “maybe a day or 2” to design something if it is of any real complexity (where a good way to measure complexity is how many interfaces exist between various systems). Give yourself at least a couple of days per non-trivial interface.

I hate the feeling of thinking that if only I had had more time my architecture would have been perfect after the first implementation. I hate even more the feeling that it honestly probably would not have been. It is never right the first time.

Or maybe I just really suck as an architect.

In any case, I am currently getting to do the implementation on a quick-turnaround (aren’t they always in the corporate world?) implementation and I am absolutely loving it. Sure, the deadline is quickly approaching. But you know what, it is my project to succeed or fail at. I am using parts of the system that I “architected” and seeing parts where I totally did not think about the problem in low-level enough detail, and trying to fix those oversights. I am getting to play with systems that I have not worked on previously. And most importantly, I am getting to code! Maybe it is the design aspects of the coding I enjoy, but I think not. What I really, truly, absolutely, love is seeing something grow before my eyes into a working system. I love the list of “//TODO” items (and love even more removing them as they get done) and bits of stub code. I love when I get surprised that it works even better than I expected. I love making a database query 10,20,30 times faster through simple application of a decent index. I love keeping 10 things in my head as I move from file to file and implement my ever-growing APIs.

I have no doubt that my methods would scare many of the purists out there. At heart, I am a “just-in-time” developer. For my emulator, I did not implement an instruction until I ran into my “not yet implemented!” exception. Same goes often for other things that I implement. It is a bit of an extreme example of YAGNE, I suppose.

Update (11/30/2007): Added some words I have left out.

Create a free website or blog at WordPress.com.