Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I am new to work but the company I work in hires a lot of non-comp-science people who are smart enough to get the work done (complex) but lack the style and practices that should help other people read their code.
For example they adopt C++ but still use C-like 3 page functions which drives new folks nuts when they try to read that. Also we feel very risky changing it as it's never easy to be sure we are not breaking something.
Now, I am involved in the project with these guys and I can't change the entire code base myself or design so that code looks good, what can I do in this situation?
PS> we actually have 3 page functions & because we do not have a concept of design, all we can do is assume what they might have thought as there is no way to know why is it designed the way it is.
I am not complaining.I am asking for suggestion,already reading some books to solve the issues Pragmatic Programmer; Design portion from B.Stroustrup; Programming and principles by B.Stroustrup;
The best and most important thing you can do is lead by example. Do things the right way and try to improve things slowly. You aren't going to fix anything overnight.
Make sure every piece of code that you are responsible for is better after you are done with it. Over time, the system will tangibly be better because of your efforts.
After you build a strong reputation with your co-workers, try go start some code reviews or lunch-training sessions to get everyone up to speed on better ways to do things.
In a nutshell: it will be difficult and frustrating, but it's possible. Good luck.
Your best bet is to NOT to handle it at all. Here are potential problems if you try:
You will be criticized for doing something you were not told to (makes performance reviews go real bad.)
You will have less time to do your own work.
You will not advance your career by cleaning working code- if it is not broke then do not touch it.
Never make enemies with people who control your career- unintentionally implying they are obsolete morons does not help your cause (especially in a bad economy).
Focus on making your own code great. Battling poorly written code is part of the ill of being a Software Engineer. You are in the wrong profession if you will not stand for it.
A little off point but important- You may need to switch jobs or teams if possible once the economy picks up. Mixing with a truckload of bad coders who do not bother to update their knowledge and practices dulls your own programming skills and weakens your marketability.
If you're a junior dev, then the only thing you can really do is write code as elegantly and readable as possible.
If your style is indeed better, other people might notice and say "hey we should adopt this formula"
Actions speak louder than complaints, which is something I noticed.
The present is embodied in Hexagram 47 - K'un (Oppression): Despite exhaustion, there may yet be progress and success. For the firm and correct, the really great man, there will be good fortune. He will fall into no error. If he make speeches, his words cannot be made good.
The future is embodied in Hexagram 6 - Sung (Conflict): Though there is sincerity in one's contention, he will yet meet with opposition and obstruction. If he cherish an apprehensive caution, there will be good fortune. If he prosecute the contention to the bitter end, there will be evil. It will be advantageous to see the great man. It will not be advantageous to cross the great stream.
I was in the exact same shoes before. I got hired as a C++ programmer to 'lead the team' on how to use C++ by an enthusiastic manager. That was about a decade ago. Some of the newer engineers loved me, the seniors despised me. Our system was basically a pseudo-C++ system. It was like C with classes, but it appeared that people didn't even understand the usefulness of things like constructors since they hardly appeared.
You complain about functions that are 3 pages long; we had functions that were 8000 lines long full of long jumps, function pointer casts, etc. One of the seniors even formatted the code with 2-space indentations so that super deep nested blocks can be written without using much horizontal space since the seniors seemed to be allergic to writing functions and procedural programming in general. Someone even inlined a 2000 line function thinking it would make things faster. You might be dealing with some bad code, but I was dealing with the most horrid copy-and-paste code imaginable.
Unfortunately I was very young and cocky. I didn't get along with the seniors, I fought against them in territorial battles over code. They responded by creating coding standards which no sane C++ programmer could follow (ex: it's okay to use operator new, but don't use exception handling, don't use constructors or destructors, etc). As a result I wrote the most bizarre and stupid standards-workaround C++ code just to kind of rebel against those standards since I refused to write C-style code given the reason I was hired (I didn't hate C so much, but writing C code was not part of the job description: I was hired essentially as a C++ consultant), even though the standards made C-style coding the only practical way to do things. I only kept my job because I put in so much overtime to make sure that my code works very well in spite of these ridiculous coding standards.
It wasn't until years later when others started to see things my way that we lifted the silly standards and started writing more natural, easy-to-read C++ code complete with STL and boost goodies, RAII, exception-handling, etc. That isolated the seniors who refused to write code in a more sane fashion and they were finally forced to adapt.
In retrospect, I could have done things much better. The seniors were intent not to allow me to be put in a teaching position, but I think I would have gotten my point across much faster with my head down. The biggest regret I have is trying to work around the impossible coding standards rebelliously rather than getting them rectified through clear and rational discussions. As a result, I have really stupid and obfuscated C++ code in the system which people attribute to me even though that's not how I normally write C++ code. The regular developers I work with understand this, but the seniors still point to it as an example of why C++ is bad.
In short, I recommend that you focus on making more friends rather than enemies. Your friends will support you, and if your way is better and you can clearly demonstrate it, you can isolate the few who will never agree.
Being enthusiastic to code the right way is a good trait to possess and in the software industry we will always encounter other developers who write code that is not quite in line with our "perfect way" of coding. This should never be interpreted as rubbish code, or inept coders, because we all start out like that in some shape or form.
Always respect your peers around you as you want them to respect you. It's certainly not easy to do in an environment that highly regards ego, but attempting to approach a topic like this is never easy.
It's how you communicate
Try different approach angles, remember you are there to learn as much as to render a service.
So commenting on the "poor" code style in an "in-your-face" kind of approach might not be the result you were looking for. So then back up a bit and try approaching the topic with "I was considering the style of code used and have a few suggestions..." and see the difference that gives.
Where I work now, the one thing I've learnt is that it's fine to comment on something that's might not be good quality but then I had better have a better solution to present.
In other words, be prepared to back up your words with useful solutions and not because you feel so.
This is the most basic reason why establishing coding standards and code review processes are a good idea.
I will not write three page functions no matter what coding standards and processes are established, but some people will. They will create 20 local variables at the beginning, without initializing any of them. You'll have pointers and integers with unspecified values. You won't know the exact meaning and scope of each variable. Etc etc.
Try to convince your manager and, later, your team, with solid arguments. Maybe you could start with a shared reading of Effective C++ or C++ Coding Standards. Try to stress the point that, when working this way and creating better code, everybody wins. If they see this as a win-win situation, they will be more open to the change.
I can empathize.
I'm below two senior programmers who have very unique styles that I find frustrating. We have code that consists of one main function that's 1000 lines long. (That is not a typo.) Our coding standards discourage globals, so we make every program one App object. Now our globals are member variables! When we need an iteration interface for C++ classes, why should we use the begin, end, and operator++ conventions, when First, AtLast, and Next can be used instead. We've wrapped up third party libraries in custom interfaces for no good reason. (We've wrapped log4cxx and lost functionality for no reason I can tell, and one of our date classes consists of a shared pointer to a boost::date object with a fraction of the functionality.)
Here's how I've kept my sanity. I've focused on the new languages and tools. This is our company's first project involving Python, and I've spent my time writing utilities and programs there. While the senior programmers code in what they're familiar with, I've got near free rein of all the Python code. I couldn't stand the C++ APIs we use, so I duplicated most of the same functionality in Python in a much more friendly way, and the other developers prefer it too.
Likewise, we have little familiarity with log4cxx and less with boost-build, both of which I've taken time to study in depth and know good enough that people come to me with questions. I've written a handful of resources on our wiki giving usage tips for log4cxx and numpy and other tools.
This is how it is, get used to it or quit and find a place where it isn't like that. You will be marginalized if you criticize their efforts and they may feel threatened if you do indeed write your own, better code or improve theirs. At the end of the day they deliver code and management sees a black box that works and that's all that matters. Plus, you'll be just another kid from college who thinks he knows something about development at a business and laughed at and ostracized when not around. Honestly, a lot of the times these systems are built like this because of shaky requirements, lots of functionality bolted on with time and managements lack of respect for a stable software development process.
Not all companies are like this. I'd start looking for a new job to be honest.
I fervently hope, this is the best opportunity to grow by facing the challenge.As Robert said,try to lead by example.If possible let them adopt your pattern.
You are not alone. I too faced recently, luckily we have support from Senior Management for Code Reviews.
1. Even a single line change for Bug fix should be reviewed online.
Comments on code can be classified as CodingStandard/Suggestion/Clarification/Major/Minor etc
While giving comments to senior you can start with Clarification/CodingStandard rather than Major
You could address the issue of "we are afraid to touch it for fear of breaking it" by writing extensive unit tests. Once you get the unit tests in place, you will be freed to refactor at will. If your unit tests still pass after the refactoring, you can be confident you haven't broken anything.
Just place a copy of "Clean Code" (Martin), "Refactoring: Improving the Design of Existing Code" (Fowler) or "Effective C++" somewhere in the office where people may start browsing the books. From now on, word will spread. Seriously, its never too late to learn! ;)
Related
my robotics lab is looking for programmers to work on some projects we have at the moment.
We nailed down the requirements (mainly, c++ and experience with openGL and 3D), but due to obvious money constraints we can't afford to hire Great Developers. Instead we're going to settle for Talented Students, offering them projects for their dissertation/thesis and hoping for some fresh ideas and creativity from their side. We can also afford to pay students that just graduated (first job experience).
So my question is:
In your experience, how did you spot a Talented Student (computer scientist or engineer)? What questions did you ask? What else did help you in finding a candidate that turned out to be a Good Programmer? (note: they might not know much about a specific language, but might have the ability to learn pretty fast)
or, if you were the interviewee,
Which questions were asked that made you jump on the bandwagon? Or, if you had an awful experience, what - in retrospect - was an obvious warning signal that you ignored?
Please note that I am not looking for an argumentative answer. We can talk all day long about what's best for us and never agree.
Instead, I'm looking for tales from your experience. Anecdotes, stories, hints, everything will help.
Background:
A bit more background: working for academia here is slightly different than working for the private sector (here = Italy). There are no 'deadlines' to 'sell' a product; instead, it's all proof-of-concept based. Nothing you start working on has the guarantee to be functional.
A comic best describes it: reinventing the wheel
I am considering doing Coding Questions for their interview, but all my colleagues are scoffing at me (too scary, nobody will ever come to work for us again, nobody really know how to code, etc).
Coding-wise, programming done by researchers is ... ugly. I am fighting to get a version control system in constant use, people have to be chased down to report bugs and document their code, everything is coded-so-that-it-works and rarely we go back to old code to 'fix bugs'. Basically once it's somewhat working, the project is closed and people go work on another project.
Lots has been reinvented and rewritten over and over again (just because nobody knew it was already there). People come and go, future is uncertain, but we play with robots so it's very cool :)
Furthermore, being really understaffed, nobody can follow you and guide you in your project. At best you're the one that has to come up with a plan, background literature and a working prototype.
Hence, we are looking for people that:
have some background to get started
can be highly independent
do want to learn and build their own expertise in new fields
Actually, here's my best advice:
Recruit among your students.
Since you work for an academic institution I assume that either you or your colleagues teach. This provides you with a wealth of information about what potential recruits are capable of -- how fast they learn, how motivated they are, what they are good and bad at, how the code they turn in for the lab assignments and projects look like, etc.
Firstly, in industry, coding questions are very much the norm - I'd be worried if coding questions weren't asked!
I've been responsible for doing technical interviews for about ten years now. And yes, I ask coding questions. But the questions themselves aren't really the point. What I'm more interested in is getting an idea of whether the candidate can think, and articulate their thoughts.
One question I ask (asuming the simple earlier stuff has gone well) is about inheritance heirachies. There is no one right answer, although there are a lot of wrong ones. But what's important is how they approach the question, the points they come up with in favour of one design over another.
Background knowledge is useful, in that it shows that they have an interest in the area in which you're working - but really knowledge can be gained. Intelligence is much more important.
However it's quite possible to have intelligent people who are impossible to work with! I haven't figured out how to determine who they are.
I have done such a project when I was a student: ie a 4-months project, working half-time. It was not about robots, per se.
I think that the most obvious requirement is motivation/passion. Since they'll be mostly on their own you will need them to be somewhat independent and able to think for themselves, this requires motivation first and foremost.
In order to determine whether the candidate is motivated or not, begin by asking them about the project itself. If they only gave it a cursory glance, they're likely not motivated. Also look at their experience / courses: optional courses in CS, projects they've done, etc... anything indicating that they really care about CS / development in general and are not there just because they've heard it paid well.
Then comes the question of ability. Like you said it might not be easy to spot those who will be smart enough to figure stuff out by themselves and DO things. Once again, you can ask them about past projects, having them detail the issues they faced and how they solved it.
Finally, I agree with you that some demonstration of their abilities is in order. They might be a bit tense initially, so I would do this at the end, once the interview is already going, you might have had a chance to get them to relax with the previous questions this way.
You don't necessarily need them to do coding questions, I think it's most about reasoning. Try to pick problems related to your area work, for example one you really had in the past, and get them to analyze the problem. If possible they should take the lead and ask you questions about the problem itself here.
We've had an issue with the robot not being able to analyze the images the camera took, it could not correctly determine the moving objects itself, do you have an idea how you would do that ?
Then you'll need to get them to think about a solution. You need a whiteboard here, and ask them to think aloud so that you can follow their reflexion. You'll probably need to nudge them a bit from time to time to keep them on track, their reaction to your input is also a key-point here, since you want them to be able to accept criticism and build on it, otherwise you might have issues directing them afterward.
Frankly, try to avoid asking them for the quicksort algorithm, or the introsort, or the radix sort... If they need sorting, they'll just fire up their computer and browse the internet. On the other hand, getting them to analyze an existing algorithm unknown to them (for example, the median of 5 sort) and checking that they understand why it works, could be worth it. If they need to work on their own, they'll need to be able to learn on their own too :)
As others say, try to hire someone that's motivated!
For master thesis students I put more emphasis on knowing the basic skills (programming, knowing how to use version control) as they don't stay on long enough to learn everything along the way.
If they're going to work mostly on their own and you have no special requirements on language I wouldn't focus much on language questions. But every decent programmer knows at least one language fairly well, get a sample or their prior work or make them code some simple application to test that they don't suck.
I'd focus more on algorithm and data structures. Ask rudimentary stuff that every programmer should know - when to use a list and when to use a vector, why summing a row-major matrix by iterating over the columns first is bad, basic complexity analysis questions, etc. That will sort out many of the bad weeds.
Ask some design questions too perhaps, e.g. what is "coupling" and why is it bad, ask them if they know what a design pattern is, etc.
Check that the applicants have a solid grasp of linear algebra and coordinate system changes in particular if they're going to work with any 3D stuff like OpenGL. In my experience, learning the API is simple, wrapping your head around how the transformations work less so.
Obviously, if you except them to perform any real robotics-specific you should check for that knowledge as well. E.g. estimation (understanding simple EKF and particle filters is a requirement in my book), control theory, pattern recognition, machine learning, vision, or whatever is useful for the particular task.
If I were hiring someone for theoretical work I would perhaps loosen up on the CS/programming skills and focus more on math knowledge. Someone with solid math skills will pick up the CS easily, and programming is just programming.
Ask for references or to see some of the prior work. Many great students already have some interesting project to show after graduation.
I'm not sure how common this is at universities in general, but I would look for a games programming (or robotics) course on the transcript where the candidate, as a student, succeeded in completing a project with a team. It would ask the candidate to describe how that project worked (important technical details) and the role he had in the team. The only way to really tell if someone is good at something is to see what happens when they try it, and since you're in academia, recruiting students, that should not be a problem.
For reasons I will spare you, I have two weeks to learn some C++.
I can learn alone just fine, but I need a good source. I don't think I have time to go through an entire book, and so I need some cliff notes, or possibly specific chapters/specialized resources I need to look up.
I know my Asm/C/C# well, and so anything inherited from C, or any OOP is not needed.
What I do need is some sources on the following subjects(I have a page that specifies what is needed, this is basically it, but I trimmed what I know):
new/delete in C++ (as opposed to C#).
Overloading cin/cout.
Constructor, Destructor and MIL.
Embedded Objects.
References.
Templates.
If you feel some basic C++ concept that is not shared with C/C# is not included on this list, feel free to enter those as well. But the above subjects are the ones I'm supposed to roughly know in two week's time.
Any help would be appreciated, thanks.
Edit: I want to clarify - I don't expect to study for two weeks and then go and write Quake.
I need to get to a level where given some code and a while to think about it, I can understand it. nuances like ++X vs X++ don't matter as much as knowing what the main keywords are, etc.
This site is your best bet. Although its a great reference anyway, the way the questions are phrased and organised you'll be able to get up to speed quicker:
http://www.parashift.com/c++-faq-lite/
I will be honest with you. In 2 weeks, you won't be able to learn the whole C++.
Let me rephrase that, because no one will ever know everything about C++ (it is very huge and yet it's still growing), you won't be able to learn everything you need to become an expert C++ programmer.
However, if you do have some good programming background, many concepts in C++ will sound familiar to you. This will help you learn complex concepts quicker than novice programmers.
I would suggest you to go to C++ FAQ Lite
because it is the site that lists all the main concepts of C++.
Don't expect to program something enterprisy after going through the site, because that ability comes after you have coded some extensive systems in C++. However, the site will definitely help you to understand what C++ looks like and other people deal with in C++.
GOOD LUCK :)
Thinking in C++, Volume II. Free, well written and available online.
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html
I know you said you didn't want to read a book but "Accelerated C++" is probably what you want. It was actually was used in like a 2 week crash course at Stanford from what I remember to get people up to speed on C++.
If you do not have time to go through an entire book, you may try an online tutorial such as the one at http://www.cplusplus.com/doc/tutorial/.
However, it will be useful to go into more depth about common pitfalls and good practice in C++. A good online resource for this is the C++ FAQ lite, at http://www.parashift.com/c++-faq-lite/ .
If you decide to buy or borrow a book, "Effective C++" by Scott Meyers would be a good choice. You do not need to read it front to back, as each chapter is dedicated to a specific problem you are likely to encounter when writing C++ code, and can be read separately.
If you need quick explanations of specific sections of the language, http://www.learncpp.com/ is also a good resource. The caveat is that their webserver is dog slow most of the time (which is unfortunate, because they have some really good explanations).
I am a new to professional development. I mean I have only 5 months of professional development experience. Before that I have studied it by myself or at university. So I was looking over questions and found here a question about code quality. And I got a question related to it myself. How do I increase my code understanding/reading skills? Also will it improve the code quality I will write? Is there better code notation than Hungarian one? And is there any really good books for C++ design patterns(or the language doesn't matter?)?
Thank you in advance answering these questions and helping me improving :)
P.S. - Also I have forgot to tell you that I am developing with C++ and C# languages.
There is only way I've found to get better at reading other peoples code and that is read other peoples code, when you find a method or language construct you don't understand look it up and play with it until you understand what is going on.
Hungarian notation is terrible, very few people use it today, it's more of an in-joke among programmers.
In fact the name hungarian notation is a joke itself as:
"The term Hungarian notation is
memorable for many people because the
strings of unpronounceable consonants
vaguely resemble the consonant-rich
orthography of some Eastern European
languages."
From How To Write Unmaintainable Code
"Hungarian Notation is the tactical
nuclear weapon of source code
obfuscation techniques; use it! Due to
the sheer volume of source code
contaminated by this idiom nothing can
kill a maintenance engineer faster
than a well planned Hungarian Notation
attack."
And the ever popular linus has a few words to say on the matter.
"Encoding the type of a function into
the name (so-called Hungarian
notation) is brain damaged—the
compiler knows the types anyway and
can check those, and it only confuses
the programmer."
- Linus Torvalds
EDIT:
Taken from a comment by Tobias Langner.
"For the differences between Apss Hungarian and Systems Hungarian see Joel on Software".
Joel on Software has tips on how to read other people code called Reading Code is Like Reading the Talmud.
How do I increase my code
understanding/reading skills?
Read read read. Learn from your mistakes. Review answers on SO and elsewhere. When you can think back on a piece of code you wrote and go "aha! I should've done xyz instead!" then you're learning. Read a good book for your language of choice, get beyond the basics and understand more advanced concepts.
Then, apart from reading: write write write! Coding is like math: you won't fully grock it without actually solving problems. Glancing at a math problem's solution is different than getting out a blank piece of paper and solving it yourself.
If you can, do some pair programming too to see how others code and bounce ideas around.
Also will it improve the code quality
I will write?
See above. As you progress you should get more efficient. It won't happen by reading a book on design patterns. It will happen by solving real world problems and understanding why what you read works.
Is there better code notation than
Hungarian one?
It depends. Generally I avoid them and use descriptive names. The one exception where I might use Hungarian type of notations is for UI elements such as Windows Forms or ASP.NET controls, for example: using btn as a prefix for a Submit button (btnSubmit), txt for a TextBox (txtFirstName), and so on but it differs from project to project depending on approach and patterns utilized.
With regards to UI elements, some people like to keep things alphabetical and may append the control type at the end, so the previous examples become submitButton and firstNameTextBox, respectively. In Windows Forms many people name forms as frmMain, which is Hungarian, while others prefer naming it based on the application name or form purpose, such as MainForm, ReportForm, etc.
EDIT: be sure to check out the difference between Apps Hungarian and Systems Hungarian as mentioned by #Tobias Langner in a comment to an earlier response.
Pascal Case is generally used for method names, classes, and properties, where the first letter of each word is capitalized. For local variables Camel Case is typically used, where the first letter of the first word is lowercase and subsequent words have their first letters capitalized.
You can check out the naming conventions and more from the .NET Framework Design Guidelines. There is a book and some of it is on MSDN.
And is there any really good books for
C++ design patterns(or the language
doesn't matter?)?
Design patterns should be applicable to any language. Once you understand the concept and the reasoning behind that pattern's usefulness you should be able to apply it in your language of choice. Of course, don't approach everything with a "written in stone" attitude; the pattern is the goal, the implementation might differ slightly between languages depending on language features available to you. Take the Decorator pattern for example, and see how C# extension methods allow it to be implemented differently than without it.
Design Pattern books:
Head First Design Patterns - good beginner intro using Java but code is available for C++ and C# as a download (see "book code and downloads" section on the book's site)
Design Patterns: Elements of Reusable Object-Oriented Software - classic gang of four (GOF)
Patterns of Enterprise Application Architecture - Martin Fowler
If you're looking for best practices for quality coding in C++ and C# then look for the "Effective C++" and "More Effective C++" books (by Scott Meyers) and "Effective C#" and "More Effective C#" books (by Bill Wagner). They won't hold your hand along the way though, so you should have an understanding of the language in general. There are other books in the "Effective" series so make sure you see what's available for your languages.
I'm sure you can do a search here for other recommended reading so I'll stop here.
EDIT: added more details under the Hungarian Notation question.
I can't speak for everyone else, but in my experience I've found that the best thing I learned about making readable and/or in general better code was reading (and ultimately cleaning) a lot of other people's code. Some people may disagree with me but I think it's invaluable. Here's my reasoning:
When you start programming, its difficult to determine what is crap vs. not crap vs. good. Being logical, rational and extremely intelligent help in making good code, but even those factors don't always contribute. By reading others works and doing the dirty work, you'll have gone through the experience of what works and what doesn't. Eventually, you'll be able to mentally navigate those minefields that others had to cross and you'll be prepared to avoid those identical minefields.
By reading other's works, you gain insight into their mind and how they tackle a problem. Just from an architecture or technique aspect, this can be very useful to you whether their
tactics were good or bad. By reading other peoples successful or unsuccessful implementation, you've gained that knowledge without putting in the actual time it took them to learn it.
Design patterns are extremely useful. Only time and experience with them will help you in knowing what the appropriate pattern for whichever problem. Again, read other peoples' code for this if they've successfully built some pattern that may be useful for you.
When dealing with extreme problems where people's work falls short, you learn to research and dive into the internals of whatever system/language/platform/framework you're working with. This research ability on your own is very useful when all else fails. But you'll never know when to start looking or for what until you get through the crud of other people's work. Good code or bad, it's all valuable in some form or fashion.
All these notations and formats and nomenclature are helpful, but can be learned or implemented rather quickly and their payoff is fairly substantial. By reading code from other people, you'll develop your own style of logic. As you encounter other peoples work and the tremendous amount of effort it takes to read through, you'll learn what logical pitfalls to avoid and what to implement the next time for yourself or even how to fix bad code even faster.
I've never felt as if I was a great programmer. Not to say I'm a bad one either, but I feel confident in my abilities as my experience has taught me so much and my ability to adapt to every situation is what makes me a solid programmer. Learning from other people and their code has helped me. Whether their work was good or bad, there's always something you can take from them and their experience, add it to your memories, knowledge, etc.etc.
Ask other people to read your code! Try and see if you get a fellow coworker or similar to have a code review with you. Having someone else comb through your code and ask you questions about your code will provide new insights and critiques to your style and techniques. Learn from your mistakes and others.
Just to give you a bit of encouragement, I've been a professional programmer for 30 years now, and I still find reading other people's code very difficult. The major reason for this, unfortunately, is that the quality of the code follows Sturgeons Law - 90% of it is crap. So don't think it's your fault if you find it hard going!
The biggest improvement in readability of my code came about when I started liberally using white space.
I found this article on Joel on Software to be very relevant to the Hungarian notation debate.
It seems that the original intent of the notation was to encode type information that wasn't immediately obvious- not whether a variable is an int (iFoo), but what kind of int it is- such as a distance in centimeters (cmFoo). That way, if you see "cmFoo = mBar" you can tell that it's wrong because even though both are ints, one is meters and the other is centimeters, and thus the logic of the statement is incorrect, even though the syntax is fine. (Of course, I personally prefer to use classes such that that statement wouldn't even compile, or would do the conversion for you).
The problem was at some point people started using it without understanding it, and the world was cursed with lots of dwFoos and bBars.
Everyone needs to read that article- Making Wrong Code Look Wrong
How do I increase my code
understanding/reading skills?
Reading code is like dancing by yourself. You need a partner, and I suggest a debugger.
Stepping through code with a debugger is a true, lively dance. I recommend getting a quality, open-source project in the language of your choice, and then step through with the debugger. Concepts will come alive if you ask "why did that happen?", "what should happen next?".
One should ultimately be able to reason about code without a debugger; don't let it become a crutch. But that said, it is a very valuable tool.
Reading code is a lot like reading literature in that you need to have some insight into the author sometimes to understand what you're looking at and what to expect. They only way to improve your comprehension skills is by reading as much code and possible and trying to follow along.
I think a lot of what is mentioned here is applicable to coding...
Reading and understanding skills are a question of time. You will improve them as you get more experienced. Also depends in the quality of the code you are reading.
Keep in mind that sometimes it's not the best idea to learn directly from what you see at work. Books will teach you the best practices and you will be able to adapt them to yourself with the experience.
I am reading the Head First Design Patterns at present and it is very useful. It presents the information in a novel way that is easy to understand. Nice to see they have a C# version for download.
There will always be struggles with reading code unless you are Jon Skeet. This isn't to say that it is a big problem, rather that unless you can eat, sleep, breathe in that programming language, it will always take a little time to digest code. Looking at other people's code is certainly a good suggestion for helping in some ways but remember that there are many different coding conventions out there and some may be more enforced than others, e.g. interface names start with an I to give a simple example. So, I guess I'm saying that even with Visual Studio and Resharper, there is still a little work to understand a few lines of code since I can't quite write out sentences in C# yet.
1) Educate yourself. Read relevant literature.
2) Write code
3) Read code
4) Read relevant blogs.
Visit http://hanselminutes.com . He is a programmer from microsoft. Even though you don't program on microsoft stack, it's good to read through. There is a podcast in there that answers this question.
Another suggestion is to make sure you have the appropriate tools for the job before you start digging into a piece of code. Trying to understand a code-base without the ability to search across the entire set of files is extremely difficult.
Granted, we very rarely have the entire set of files, especially in large projects, but whatever boundaries you draw, you should have good visibility and searchability across those files. Whatever lies outside those boundaries can be considered 'black box' and perhaps lies outside the scope of your grokking.
There are many good open source editors including Eclipse and the CDT. Spending some time learning how to effectively create projects, search across projects, and enable any IDE-specific tooltips/helpers can make a world of difference.
I'm just now learning to programming at age 17. It's hard for me to talk to other programmers as I'm just out of high school (which means I can't take programming courses). I know that I write terrible code, and not like Jeff Atwood terrible code, my code actually sucks. So where can I post some of my code and get real programmers to review it. I know if I had a question I could ask it on StackOverflow, but I want to post a whole class and get a review on it.
The real problem here is that I'm not going to be writing the next great piece of Software. I'm going to be writing a really useless class, which will serve no other purpose than to teach me how to program. This code will never be used, ever! EVER! How can I get an advanced (or even intermediate) programmer to look at my code?
Thanks in advance! ;-)
Look to the open source community. There are plenty of existing and new projects that would love an eager (if inexperienced) developer to offer support.
Going this route offers two advantages:
You get to see great code in action and learn from it
Any changes you submit will be reviewed by an experienced developer and they will often give you excellent suggestions as to how to improve your code before it will be accepted
Start by choosing a project in your language (there are a bunch in c++) and check out the code. You don't need to understand it all, but you must be able to understand at least a portion of it.
If the project looks way to complicated, keep looking. Younger projects tend to have less code that you need to learn.
If you can't get great programmers to look at your code, do the next best thing: look at theirs!
Look for a bunch of code snippets that do the same (simple) thing. Before you look at them too closely, write your own code to perform the same task. Compare all of the snippets with your own (and each other!) and try to figure out the reasons for the differences.
I recommend looking for code from well established projects. Code from tutorials often ignores important details for the sake of simplicity.
Why don't you try RefactorMyCode?
I would try not to write useless code, but attempt to solve some particular problem. Your learning will be more advanced if you are learning in the context of a real-world scenario. It doesn't have to be a big business domain; could even be a game or a shareware utility.
As for getting your code reviewed, the open source community is a good way to go as The Lame Duck says - in fact you're guaranteed it gets some form of review if you actually contribute to a project. Other avenues to explore: your local C++ users' group, checking out a co-op program available through a junior college, or engaging someone in a company that sponsors interns.
I haven't tried sites such as RefactorMyCode as suggested by Gilad Naor, but that seems promising. And, yes, StackOverflow is a good place for bite-sized chunks of code. If you do that, explain what you are trying to do, and why you are trying to do it that way, and ask if there's a better approach. Good luck!
I think the best way to learn is the way I learned (I may be biased): trial and error. I just wrote programs all the time, teaching myself as I went. I'd write terrible code, and I would wrestle with making it do what I wanted. Often it would make me give up on that particular project. But on the next project, I'd take a different approach, and it would work better. Repeat ad nauseam. Once you know where the rough spots are in your designs, you'll be able to ask specific questions on places like SO, or, better yet IMHO, come up with better designs yourself. I independently invented all the major design patterns just through frustration at the solutions I'd created in the past. I think this gives me a valuable perspective, since for most people design patterns are just a "best practice", but I know the pain that comes with using other designs, and I can see signs of bad designs in code very easily (it takes one to know one). This last skill is one that I often see lacking in other programmers... they can't see why their design is deficient and they should use something else.
You could always try a site like Project Euler, where there are a whole load of problems that will test your skills and a whole bunch of solutions to those problems, submitted by others. Project Euler tends to focus on algorithms rather than higher level programming constructs, but I imagine that there are others in a similar vein.
Do something fun and don't worry too much about code style yet. I started out with BASIC on Commodore 64 without even realizing that there was such a thing as clean code vs dirty code. If I had worried a lot about that then, it might have hindered me from progressing. You always learn best when doing it playfully.
Maybe a bit late, but since StackExchange has Code Review, it worth the answer:
Code Review Stack Exchange is a question and answer site for peer
programmer code reviews. It's 100% free, no registration required.
Here is the link: Code Review Stack Exchange
I'm a programmer with 2 years experience, I worked in 4 places and I really think of myself as a confident, and fluent developer.
Most of my colleagues have CS degrees, and I don't really feel any difference! However, to keep up my mind on the same stream with these guys, I studied C (read beginning C from novice to professional), DataStructures with C, and also OOP with C++.
I have a reasonable understanding of pointers, memory management, and I also attended a scholarship which C, DataStructures, and C++ were a part of it.
I want to note that my familiarity with C and C++ does not exceed reading some pages, and executing some demos; I haven't worked on any project using C or C++.
Lately a friend of mine advised me to learn C, and C++ extensively, and then move to OpenGL and learn about graphics programming. He said that the insights I may gain by learning these topics will really help me throughout my entire life as a programmer.
PS: I work as a full-time developer mostly working on ASP.NET applications using C#.
Recommendations?
For practical advancement:
From a practical sense, pick a language that suites the domain you want to work in.
There is no need to learn C nor C++ for most programming spaces. You can be a perfectly competent programmer without writing a line of code in those languages.
If however you are not happy working in the exact field you are in now, you can learn C or C++ so that you may find a lower level programming job.
Helping you be a better programmer:
You can learn a lot from learning multiple languages though. So it is always good to broaden your horizons that way.
If you want more experience in another language, and have not tried it yet, I would recommend to learn a functional programming language such as Scheme, Lisp, or Haskell.
First, having a degree has nothing to do with knowing C++. I know several people who graduated from CS without ever writing more than 50 lines of C/C++. CS is not about programming (in the same sense that surgery is not about knives), and it certainly isn't about individual languages. A CS degree requires you to poke your nose into several different languages, on your way to somewhere else. CS teaches the underlying concepts, an understanding of compilers, operating systems, the hardware your code is running on, algorithms and data structures and many other fascinating subjects. But it doesn't teach programming. Whatever programming experience a CS graduate has is almost incidental. It's something he picked up on the fly, or because of a personal interest in programming.
Second, let's be clear that it's very possible to have a successful programming career without knowing C++. In fact, I'd expect that most programmers fall into this category. So you certainly don't need to learn C++.
That leaves two possible reasons to learn C++:
Self-improvement
Changing career track
#2 is simple. If you want to transition to a field where C++ is the dominant language, learning it would obviously be a good idea. You mentioned graphics programming as an example, and if you want to do that for a living, learning C++ will probably be a good idea. (however, I don't think it's a particularly good suggestion for "insights that will help throughout your live as a programmer". There are other fields that are much more generally applicable. Learning graphics programming will teach you graphics programming, and not much else.)
That leaves #1, which is a bit more interesting. Will you become a better programmer simply by knowing C++? Perhaps, but not as much as some may think. There are several useful things that C++ may teach you, but there also seems to be a fair bit of superstition about it: it's low-level and has pointers, so by learning C++, you will achieve enlightenment.
If you want to understand what goes on under the hood, C or C++ will be helpful, sure, but you could cut out the middle man and just go directly into learning about compilers. That'd give you an even better idea. Supplement that with some basic information on how CPU's work, and a bit about operating systems as well, and you've learned all the underlying stuff much better than you would from C++.
However, some things I believe are worth picking up from C++, in no particular order:
(several of them are likely to make you despair at C#, which, despite adopting a lot of brilliant features, is still missing out some that to a C++ programmer seems blindingly obvious)
Paranoia: Becoming good at C++ implies becoming a bit of a language lawyer. The language leaves a lot of things undefined or unspecified, so a good C++ programmer is paranoid. "The code I just wrote looks ok, and it seems to be have ok when I run it - but is it well-defined by the standard? Will it break tomorrow, on his computer, or when I compile with an updated compiler? I have to check the standard". That's less necessary in other languages, but it may still be a healthy experience to carry with you. Sometimes, the compiler doesn't have the final word.
RAII: C++ has pioneered a pretty clever way to deal with resource management (including the dreaded memory management). Create an object on the stack, which in its constructor acquires the resource in question (database connection, chunk of memory, a file, a network socket or whatever else), and in its destructor ensures that this resource is released. This simple mechanism means that you virtually never write new/delete in your top level code, it is always hidden inside constructors or destructors. And because destructors are guaranteed to execute when the object goes out of scope, even if an exception is thrown, your resource is guaranteed to be released. No memory leaks, no unclosed database connections. C# doesn't directly support this, but being familiar with the technique sometimes lets you see a way to emulate it in C#, in the cases where it's useful. (Obviously memory management isn't a concern, but ensuring that database connections are released quickly might still be)
Generic programming, templates, the STL and metaprogramming: The C++ standard library (or the part of it commonly known as the STL) is a pretty interesting example of library design. In some ways, it is lightyears ahead of .NET or Java's class libraries, although LINQ has patched up some of the worst shortcomings of .NET. Learning about it might give you some useful insights into clever ways to work with sequences or sets of data. It also has a strong flavor of functional programming, which is always nice to poke around with. It's implemented in terms of templates, which are another remarkable feature of C++, and template metaprogramming may be beneficial to learn about as well. Not because it is directly applicable to many other languages, but because it might give you some ideas for writing more generic code in other languages as well.
Straightforward mapping to hardware: C++ isn't necessarily a low level language. But most of its abstractions have been modelled so that they can be implemented to map directly to common hardware features. That means it might help provide a good understanding of the "magic" that occurs between your managed .net code and the CPU at the other end. How is the CLR implemented, what do the heap and stack actually mean, and so on.
p/invoke: Let's face it, sometimes, .NET doesn't offer the functionality you need. You have to call some unmanaged code. And then it's useful to actually know the language you might be using. (if you can get around it with just a single pinvoke call, you only need to be able to read C function signatures on MSDN so you know which arguments to pass, but sometimes, it may be preferable to write your own C++ wrapper, and call into that instead.
I don't know if you should learn C++. There are valid reasons why doing so may make you a better programmer, but then again, there are plenty of other things you could spend your time on that would also make you a better programmer. The choice is yours. :)
Experience is the best teacher.
While you can read about things like memory management, data structures (and their implementations), algorithms, etc., you won't really get it until you've had a chance to put it in to practice. While I don't know if it's truly necessary to use C or C++ to learn these things I would put some effort into actually writing some code that manages its own memory and implements some common data structures. I think you'll learn things that will help you to understand your code better; to know what's really going on under the hood, so to speak. I would also recommend reading up on computer organization and operating systems, computer security, and boolean logic. On the other hand, I've never really found a need to do any OpenGL programming, though I did do some X Windows stuff once upon a time.
Having degree has got nothing to do with C/C++ actually. Now, stuff like big O() estimation, data structures or even mathematical background. For example linear algebra results very useful, even in context that seemingly have nothing to do (eg. search engines).
For example typical error that a good coder, but without any theoretical knowledge, might commit is to try to solve NP-complete problems by exact algorithm, rather than approximation.
Now, why in universities they teach you C/C++? Because it let's you see how it's all working "under the hood". You get opportunity to see how call stack works, how memory management works, how pointers work. Of course you don't need that knowledge to use most modern languages. But you need that to understand how their "magic" works. Eg. you can't understand how GC works, if you got no idea about pointers and memory allocation.
I've often asked this question (to myself). I think the more general version is, "how can I call myself a programmer if I don't know how to kick around a language that doesn't have automatic garbage collection, with pointers and all that 'complex' stuff'?" I've never learned C++ except to do a few HelloWorlds, so my answer is limited by that lack:
I think that the feeling that you need to learn C++ (or assembler, really) comes from the feeling that you're always working on someone else's abstractions: the "rocket scientists" who write the JVM, CLR, whatever. So if you can get to a lower level language, you'll really know what you're talking about. I think this is quite wrong. One is always building on a set of abstractions: even Assembler is translated into binary, which can be learned as well. And beyond that, you still couldn't make a computer out of firewood, even if you had a pair of pliers and a bit of titanium.
In my experience as a corporate trainer in software dev (in Java, mostly), the best people were not those who knew C++, but rather those that took the language that they are working in as an independent space for "play." Although memory management comes up all the time in C# and Java, you never have to think about anything beyond freeing your object from references (and a few other cliche places, like using streams instead of throwing around huge objects in memory). Pointers and all that stuff do not help you there, except as a right of passage (and a good one, I'm sure).
So in summary, work in the language you're in and branch out into as many relevant things as possible. These days I find myself dipping into Javascript though the APIs are supposed to make this unecessary, and doing some stuff in Fireworks while I mess with CSS by hand. And this is all in addition to the development I'm really doing in RoR, PHP and Actionscript. So my point is: focus on abstractions that you need, because they're more likely to be relevant than the lower-level stuff that underlies your platform.
Edit: I made some slight changes in response to jalf's comments, thanks.
I have a 1st class Software Engineering degree and work for a large console manufacturer developing a game engine in a team of programmers all of whom program across a wide range of languages from Asm to C++ to C# to LUA and know the hardware inside out.
I would say that 5% of my degree was useful and that by far and away the most important trait to furthering my career has been enthusiam and self development.
In fact many of the colleagues I've worked with haven't had a degree and on average have probably been the better ones.
I'd say this is because they've had to replace that piece of paper from a university degree with actual working code that they've developed in thier own spare time learning the skills off thier own back rather than being spoon fed it.
My driving instructor use to tell me that I would only start learning how to drive after I pass my test ie you only really learn from the practical application of the basics. A CS degree gives you the basics which if you've had a job programming any of the major languages for 6 months you will already have. A degree just opens up doors that you may not have otherwise - it doesn't help that much once inside the door.
Knowing how the software interacts with the hardware by the sounds of it is the most important area for you at the moment only then does the 'mystery' or 'magic' really disappear and you can be confident of what your talking about else where. Learning C and C++ will undoubtedbly help in this respect as will knowing an API like OpenGL.
But I'd say the most important thing is to find something you have interest in and code that. If you have real enthusiam for it you will naturally learn more low level information and become a better programmer, if indeed that is what your definition of being a better programmer is!
I've been working as a developer with no degree for almost 15 years now. I started with Ada and moved quickly into C/C++, but it's been my experience that there will always be some language that you "have to learn." If it's not C++, it will be C# or C or Java or Lisp. My advice is make sure you're solid on the basics that apply to any language(my best friend as a dev with no degree was the CLR book), and you should be able to move relatively easily between languages and frameworks.
You don't absolutely have to learn C/C++, but both languages will teach you to think about how your software interacts with the underlying OS and hardware, which is a essential skill. You say that you already know about pointers, memory management and so on, which is great. Many programmers without a CS degree lack this important knowledge.
Another good reason to learn C/C++ is that there's a lot of code written in these languages and a good way to learn more about programming is to read other people's code. If you're interested in writing low level code like drivers, OS, file systems and the like C/C++ is pretty much the only way to go.
Do you have to learn it extensively? I expect not.
However it's best to always be learning things that help you look at programming from a different perspective. Learning C or C++ are worth it for the insight into how things work at a lower level. For C and C++ programmers the same thing might be accomplished by learning assembly. Most people won't use assembly in a project, but knowing how it works can be very helpful from time to time.
My recommendation is always to learn as much as you can. If you're not working on a C++ project in the near future I wouldn't be too worried about learning the ins and outs, but it's always good to be able to look at problems from another angle and learning new languages is one way to do that.
Today for the majority of applications, C and C++ can be viewed as an academic exercise: "How can we write programs without garbage collection?"
The answer is: you can, but it's a mostly painful experience. Most of the details of best practices in C++ are related to the lack of garbage collection.
Given the brilliant performance of modern GCs, and the general increase in computing power, even cell phones have GCs these days. And in a platform with a GC, you can always code in such a way as to limit the pressure you put on the GC.
Listen or read SO podcast 44, where Joel plays his favorite song Write in C
Spolsky: Yeah, it's not paying the proper royalties to the Beatles anyway. We'll link to that from the shownotes. Awesome song, Write in C.
Atwood: That's right, Joel's favourite song. Write everything in C, because Joel does in fact write everything in C, don't you, Joel?
Spolsky: I started using a little bit of C99, the latest version of C, which let you declare variables after you written some statements.
...
Without a professional reason (other than the good practice of self-improvement) to learn C or C++, then you should have a passionate side project planned out that you could write in C or C++. Once the going gets tough on the side project, you'll need your enthusiasm and curiosity to take you over the hump (since on a side project, you naturally don't have the motivation of pay or de-motivation of a superior looming over you).
Also, most CS degrees are using Java as their language of choice now. This just proves the point that experience gained in the language of choice and exposure to some of the theory involved in the other classes in the degree is the main benefit for people with CS degrees, and not so much the specific language (though I think the higher they go up the abstraction scale, the worse it is for the students in the long run).
Without a practical reason for learning a programming language it is pretty hard going.
If you can think of particular problems or a specific task which the language is suit for - Then the learning experience is driven by needs, rather than simple academics.
I only just recently switched from VB to C# (1 month ago) while not as significantly different as a switch from C# to C, because I switch for a particular reason I found it much easier to learn. I had dabbled previous without a specific problem to solve, needless to say I switched back
If you have a different style of learning as in self-taught then my recommendation to be a better programmer is to research topics regarding your domain. From bottom to top, slowly climb up the ladder.There is a fairly amount of different programmers, no one will excel in all, so don't start off with that context in mind.
Best of luck to you.
C++ is just a programming language. What you don't have that other students (if they paid attention in class) have is the deeper understanding that comes through studying concepts.
Being a programmer is not and should not be the end goal of any CS graduate. However it is as far as most people get without such a degree.
Here is an analogy: An engineer and an architect both at some point learn to draft buildings using CAD. Also, someone completely untrained can come in and start work using CAD and be very effective. This is a good career and it pays well, but for both the engineer and the architect it is not where you want to be when you are 30.
One value of knowing C is that many other languages including C#, Java, C++, JavaScript, Python, and PHP have their roots in C syntax.
Another value, and arguably more important, is that it will build your confidence. Programmers are a confident group and very optimistic (you have to be confident to think that you can write the equivalent of a 1000 page book without a single spelling or grammatical error). And confidence in your ability to learn and effectively use any language will grow considerably with a pure C application or two under your belt.
So write a non trivial program in C; something that at least reads and writes files, allocates and deallocates memory, and manages a data structure like a queue or binary tree.
Your confidence will thank you.