Programmers make mistakes, it becomes a bad habit when they do not learn from the mistakes. Learning from mistakes and adding good practices makes their career stable. Here is our compilation of what separates the wheat from the chaff and how programming taboos can be avoided. This will help developers bring in better servicing quality and a much better customer experience for the client.
1. Not honing non-technical skills – We consider non-technical skills a major contributor to project success. It is the soft skills demonstrated by the company as a whole that drives long-term business relationships with clients and thus determines the development company’s growth path. Some key indicators here would include –
a. Discipline – One of the most critical traits, lack of discipline instills non-confidence in the ability of the development team. Some ways in which this can be rectified include setting up a detailed to-do list every day, staying on top of your commitments, completing what you start, and avoiding multi-tasking, as it tends to generate chaos.
b. Customer empathy – Not keeping the client at the core of your decision really defeats the whole purpose of why we do business. Having world-class expertise and resources will not help if the customer is not happy. Keep solutions delivery in line with client expectations and your project will deliver true value.
c. Communication – Clear and timely communication is sadly a servicing void that needs to be filled for development projects especially when clients and vendors are not in the same geography. Concentrate on three aspects and you will be able to overcome this problem – be focused around the topic to be discussed, be clear, and be crisp or concise.
d. Understanding requirements – In development life cycle, there comes across a vital difference between success and failure. The initial brainstorming to understand the problem statement and providing subsequent deliveries, need to complement each other. Only then will your work be appreciated by the client. You can also schedule partial deliveries, or in batches so that revisions from client end are incorporated in the final delivery.
2. Not being judicious about the coding – Every programmer thinks that his/her code is the best. Equally true is the fact that for every code, there are many other ways to implement the same and other programmers will inevitably find perceived flaws in one version of code over another. Also, when collaborating on a project, there is bound to be friction between programmers to demonstrate who the best is. While healthy competition is good, it should not be at the cost of a successful and seamless project.
Another creative block is the inability to use predefined templates to your advantage in a development project. Almost all programming languages have a good online/inbuilt repository of code snippets that can be patched in to prevent re-programming from ground up. However, reasons such as not understanding requirements or a lack of exposure to the various available libraries/templates mean that programmers inadvertently end up creating a code which is already present in the first place. This not only adds to the time but also escalates costs. Additionally, a published piece of code has already been tested for quality, so it just makes sense to go for templates wherever possible.
3. Not keeping it understandable – Consider the following scenarios –
a. You may be getting a handoff from another team member. Imagine being forced to spend hours trying to decipher just one line of code because of the absence of a helpful comment.
b. You may be programming today and if you re-look at the same code some months down the line, it could be difficult to imagine what a ‘weird’ code is doing in the middle of the program .
c. You may be reviewing your team’s work and face the problem of not understanding what some code does in the absence of explanatory comments.
d. You may have cracked a brilliant way of programming certain logic. What’s the point if others (or you too after a few weeks) are unable to figure out what it means because there was no accompanying comment?
In addition to the problems caused by a lack of commenting, or poor commenting, is the problem of not giving meaningful names to variables in the program. Many programmers simply run out of meaningful names to give to their variables. If you come across a variable ‘test3’, I am sure you would have to pass through multiple iterations of back checking how it was created, where it was used and what value does it output, which leads to a waste of time and energy. And this is just one variable we are talking about.
These are very real causes of programming woes that warrant the use of putting explanatory comments and using English sounding names of variables wherever needed. Some basic pointers to get your program to be understandable includes the following:
a. Keep all parameters, references, methods, and variable names as close to English as possible. Keep names short but helpful to understand the functionality.
b. Wrapping text using ++ is a good way to make code and comments legible.
c. Keep your programming in a continuous flow. Use of ‘goto’ and ‘return’ multiple times to direct the flow from one part of the program to another should not be unnecessarily employed, especially in OOP based languages such a C#, C, and C++.
d. Have descriptive names for blocks of code in different methods. Having well-named methods calling other well-named methods makes reviewing the program easy and quick.
4. Not using proven tools and techniques – A programmer is as good as the tools he or she employs for programming and debugging. For exception tracking, the two common mistakes that programmers do are –
a. Catching a general exception which may have an impact on others codes. Working on such generic exceptions (instead of specific exceptions) would mean that inadvertently the exception will be suppressed throughout the program and thus remain untreated in others’ code.
b. A programmer might also have spiteful intentions of catching all exceptions but not doing anything about it. Known as “empty catch block”, such exception handling compromises the stability and security of the entire software.
Instead of continuing with execution using blank try-catch, one can narrow down to specific problems such as invalid code exceptions and out-of-memory exceptions.
5. Poor version control On any project involving multiple team members, it is a cardinal sin not to introduce the usage of best practices when it comes to version control. Version control ensures that edits or revisions made by one person do not impact the work of another person. Version control not only helps combine the concurrent editing done by two or more programmers, but it also keeps track of the history of changes made to the program. Some good practices that should be done to ensure strong version control include:
a. Creating a logical unit for each ‘commit’ – Ensure that every single commit solves just one specific purpose and use it only for that purpose. Future review of the program and debugging becomes easier if this point is in place. If a code for a specific purpose is kept in different ‘commits’ then the version control system’s utility will be diminished. On the other hand, if a single ‘commit’ solves multiple purposes, then it becomes necessary to save all edits and then re-apply them in logical chunks, committing as you progress ahead.
b. Giving a descriptive ‘commit’ name – Make sure to add a descriptive comment at the point of ‘commit’. Adding a commit message takes half a minute, but serves an important purpose of explaining clearly what the commit does and what change does it plan to implement the program. This may help a third person or yourself in the future as it is not easy to remember every instance of the commit.
c. Making sure you are working with most up-to-date files – This involves incorporating others’ edits as frequently as possible so that your version control returns the latest results. Use commands such as ‘svn update’, ‘git pull’ or ‘hg fetch’ every once in a while so that all latest revisions by others get added to the project. This becomes necessary when people are working closely on a related module and the revisions of one programmer impacts the other programmer.
d. Share your changes frequently – On the other hand, keep sharing your changes using the ‘git push’ or ‘hg push’. This ensures that other programmers keep working with latest copies of your program construct. Holding the copies locally will make it difficult to prevent re-creating the wheel or bringing in programming conflicts. So it makes complete sense to keep ‘pushing’ your program updates from your local location to a central repository as often as possible.
6. Not keeping oneself updated This is an interesting one. All businesses want to impress their clients with their agile techniques and knowledge but very few actually take the time to hone the learning curve of their employees. Many companies simply provide basic training and expect employees to learn on live projects. They do not factor in that and this increases overheads on the business manager and the immediate supervisor to maintain a high quality of the work they are producing. This difficulty can be overcome in two ways:
a. When a new team member joins, it is imperative to take him or her through a set of a training program that is in line with the roles that they are expected to perform. For instance, if a new tester is coming on board, a basic introduction to programming concepts should be carried out at the start. The majority of the training then should concentrate on providing best practices for testing rather than continue elaborating on programming.
b. The technology landscape is evolving faster than ever. Keeping this in mind, ensure that there are periodic training sessions especially for long-standing employees who have proved their mettle with their stellar performance. For instance, a web designer will need to know (rather than good to know) responsive web design, given the massive proliferation of mobile devices in customers’ lives.
7. Inadequate testing Testing as a vital element of the entire SDLC is usually not given the required prominence by development teams. It is simply a sin to not put adequate and relevant efforts into the testing process. Below are some ways in which testing can be used as a powerful weapon in your drive for producing quality checked deliverables for the customer.
a. Unit Tests – At the time of testing within applications, a unit test is a most commonly preferred method. Under this the entire unit is tested against expected functionality by calling the relevant utility methods, passing values to variables and checking if the unit is performing as required. Note that sometimes testers use arbitrary values for the unit test. This is a big mistake. Instead of using random values and increasing iterations, use boundary cases (negative values, maximum values, null values, etc.). Also check if exceptions are handled correctly, and are descriptive.
b. Mock-ups – If you are testing the service layer and its associated helpers or one-offs, then mock comes in handy. However, mock classes are usually tightly integrated and manual testing will not help much. Here, external mocking frameworks such as Mockito and EasyMock come in handy. Choose one of the frameworks depending on the extent of usability and the amount of learning curve involved.
c. Integration Tests – Moving on from Logical Unit tests, we can also test across different integrated components of an application. DAO layer testing is one example of Integration Test. One mistake commonly made here is the providing of test data in XML format. This data doesn’t align to live data. So the best way to maximize the potential of an integration test is to involve operational personnel and provide them with Excel data to test integration.
8. Security lapse – Some of the most impact security lapses at the time of software development are as under –
a. Unexpected interaction between different components – These include:
i. Improper input validation – Check that input obey the requisite expectations. If a text field expects certain data then only valid data values should pass as input.
ii. SQL injection – Ensure to use parameter based SQL queries and enforce separation between data and code. This way hackers cannot modify the queries to steal or bypass data authentication.
iv. OS Command Injection – This is the 2nd biggest security lapse after SQL Injection. Here calling up third party programs or code can expose your software to allow hackers to run their own commands from your IT resources. Running external calls in a sandbox environment is a good way to tackle this problem.
v. Cross Site Request Forgery (CSRF) – This is a new type of phishing whehttp://www.veracode.com/security/csrfre an attackers’ site looks identical to a genuine site. Use a vetted library or framework such as OWASP CSRFGuard or the CSRF module of ESAPI session management control.
b. Unfeasible resource management – These include:
i. Not respecting available memory buffers – Buffer Overflow is a significant problem in C based languages. Using an input without checking its memory requirement leads to unnecessary crashes and exceptions. One good way to tackle this at the programming stage is to use programming languages such as Perl, C#, and Ada that provide inbuilt functionality to check for and eliminate buffer overflow problem.
ii. External control – If you download external code and execute it, you are open to vulnerabilities by external attacks and control. Your software will behave unexpectedly and often maliciously when under an attacker’s control. Taking steps such as eliminating DNS spoofing and code encryption prior to transmission, or even running code as an isolated instance will mitigate the risk arising from this issue.
iii. Use of potentially dangerous functions – Library or API functions acts as powerful tools for developers. However, these API’s can compromise the integrity of the software if not used in the right context. Developers need to make note of these and make a list of prohibited functions within the organization to cut down on such risks.
9. Communication with clients – After the initial contract is signed, the development company often forgets ignores the day to day interaction with the client and works in isolation till the point of delivery or a big escalation. Keep in mind that clients have entrusted this particular portion of their work to your company because you have the skills in that domain. If so, then make sure you reinforce this trust by providing constant updates on the progress and proactively inform the client in case of delays or technical concerns. Keeping the client in the loop (especially when they are in different geographies) helps ensure peace of mind to clients and keeps them happy during the project execution. Two key communication factors drive long-term relationship with the client.
a. Communicate before they ask – A proactive nature of communication helps provide clients with much needed time to think of ways to tackle a problem at hand. For instance, if a delivery on June 2nd doesn’t seem possible, it would be unprofessional and discouraging to inform them on June 1st about this. Make sure to inform them well in advance about any impending delays so that they can get time to work out these problems . The same goes for budget delays, module delivery delays, getting stuck at a particular point of the project etc.
b. Communicate periodically -– Clients are delighted by vendor partners who keep them in the loop about the progress of the project. Giving small yet meaningful updates helps them understand that the project is on track. Even after final delivery, you can give a courtesy call to ask how the software is functioning and if any assistance is required.
10. Avoiding standard practices in the face of looming deadline – Often, projects run into schedule delays. However, this doesn’t give you the freedom to cut corners in either the development or in the testing of incomplete and untested modules. A better way to manage the delay is to inform clients upfront and proactively about the delay in execution. As long as the reasons are valid, the, the client should understand and give you extra time to work out the problem.
While it may apparently save time at the time the decision is made to finish the programming within deadline with poor coding, overall more time and efforts would be spent if major development issues are not factored in right from the commencement of the project. Re-engineering resources to work on revisions is not a productive use of time. Companies would rather spend some more time in initial development so that the final output conforms to SDLC standards and is free of defects and issues. For clients, timeliness cannot be at the cost of quality, ever.