Thursday, December 29, 2005

10% time for productive fun

Someone was telling me a few days back about a certain software company that lets employees work on whatever they wish for 20% of their working week. Jim Shores has written an article on a very similar concept. In his article Jim explains the benefits of letting employees spend half a day every week researching any technology or area of their choice. Even if the research is not of immediate importance to the project they are working on, they will still benefit tremendously from the enhanced perspective. Jim mainly talks about spending the research time on technology and working up a small prototype to demonstrate a concept and to increase ones own understanding. The article is available on Jim's website

Along with experimenting with code, other activities that may also yeild good results are reading articles or blogs written by senior software practioners, listening to podcasts, writing, and teaching.
Many articles written by senior developers are very insightfull, because they write about things that they have learned in the trenches. Some are also thought provoking and challenge conventional wisdom. Those who prefer listening will find that some podcasts are extremely informative. Writing and teaching is also a wonderfull way to learn. Both these activities make us think deeper about a topic and very often I have been surprised to learn that there is so much more to a topic that I thought I already knew well.

Jim mentions in his articles that most people who followed his advice were very pleasantly surprised with the results.

Benifits of blogging

A few days back I was discussing with a friend, how small companies can use blogging to their advantage. To survive in business each company has to maintain a certain brand image for itself. The brand image helps in attracted good customers as well as in attracting good talent to work for the company. Large organizations do the brand building in many ways, some of them being through advertisements, brochures, conferences, and their salesforce. Small companies however do not have the deep pockets that their larger counterparts enjoy, but many small companies do excellent work, and it's a pity that they are not as well known as they should be. The Internet and the concept of grassroots publishing gives smaller organizations, the tools to network and make themselves better known. Blogs and Podcasts are two of the more frequently used tools that can be used. In this weblog I talk about Blogs. I will to talk about Podcasts in another posting.

Blogs as opposed to books capture small ideas. A book is a treatise, it deals with a concept, fact, or fiction in significant detail. An article is a smaller unit of writing, and a blog is the smallest. In a blog one writes about something distinct in a terse and useful manner. Offcourse not all blogs are terse and many are not useful, but that is because there are so many bloggers, all of whom want to share their personal rants with the world.

A blog may proceed towards a book, but it need not. It can be a collection of thoughts, stories, etc that we want to share with our readers. Let me explain why it is important. A couple of days back I was reading Times Ascent. There were recruiting advertisements from well known companies (most of those adds were large and in color), and there were adds from smaller companies. I am sure some of the smaller companies must be really good, but anyone reading Ascent has no way of knowing it. Applicants looking for a job will first apply to the larger organizations, and only those candidates who are not sure of getting selected with the big guys will look at the unknown companies. I think there are two factors that come into play here. The size and the glitz of the advertisement, and the fact that a company is known. An advertisement that does not have any of these factors will most likely be ignored by the good candidates. Size and glitz come at a huge price, and probably are not affordable for a small organization. But being known in the software community is not very difficult. As an example, Joel Spolsky runs a small software company which is reasonably well known and he is also able to attract good talent. He gets summer trainees from Stanford. He has achieved this because he has created a certain persona for his company through his writings (essentially blogs) on the Internet. I am sure it takes time, but the returns that he gets are definitely worth it.

For a practical implementation outlook, all that needs to be done is spend 15 minutes a day writing about experiences with methodologies and technology. It can be a collaborative process where everyone contributes and something good emerges at the end of every week. At times it can also be a personal effort and not a collaborative one. Time spent on this activity will not be wasted, because the process of writing also helps the writer articulate her thoughts, and not to mention write better comments in code :-) If an organization can come up with short peices of useful writing, publish them on their website, and also get them published in magazines then they will create a certain rapport with the software community. The name of the organization will stick in peoples mind. Now when the organization advertises for job openings, they will get a better response because more potential candidates will have heard of the company, and will know that they do good work. In time the advertising can also happen through the blogs. Very often talented developers might apply on their own, because they want to work for a company that does great work. Off course it will be a while before this will happen, but as they say: A long journey begins with the first step.

Tuesday, December 06, 2005

Writing tip: usage of commas

An interesting writing tip from http://www.GrammerCheck.com
---------------------------------------------------------------------------------------
QUESTION: "Now that spring has arrived, the flowers are in bloom, and the trees are budding." This is a sentence my English teacher gave us in class, and I told her that it was wrong and she needed to drop the second comma. She disagreed and said it was right as is.

GRAMMARCHECK: Your teacher is correct. The sentence in question has one dependent clause and two independent clauses:

Dependent Clause: Now that spring has arrived

Independent Clause #1: The flowers are in bloom.

Independent Clause #2: The trees are budding.

The first comma is necessary because a comma should be placed after an introductory [dependent] clause. The comma separating the two independent clauses is optional because both clauses are short and closely related; however, it's never incorrect to place a comma between two independent clauses that are joined with a conjunction.

Friday, December 02, 2005

Free Books

1. Would you like to listen to free audio books? Check out LIBRIVOX.
It contains audio recordings of many old copyright-free books, like Sherlock Holmes, P. G. Wodehouse, etc.

2. Here is a free e-book on the Java programming language. It uses Applets to illustrate certain concepts more clearly.

Friday, November 25, 2005

Case of the stingy JVM

Did you know this ?
-----------------------------------------------------------------------------------------------------------------
The Java virtual machine specification defines the range of values for each of the data types, but does not define their sizes. The number of bits used to store each data type value is a decision of the designers of individual implementations.
-Bill Venners, Inside the Java Virtual Machine
------------------------------------------------------------------------------------------------------------------
When you create an int you would think that the JVM allocates 32 bits to it. But wait, it is possible that it may allocate fewer bits if the value you assign to the int does not require all the 32 bits. What will happen if you assign it a larger value? I do not know for sure, but I think it will relocate the int to some other location on the heap and give it more memory.
Now is that 'stingy' or 'smart' ?

FLOSS.IN

This year Bangalore Linux is being hosted as FLOSS.IN from Nov 29th - Dec 2nd.
The speakers and topics seem very interesting. I am sure the event will be a great learning/exploring oppurtunity for the participants. Check the link for more details.

Wednesday, November 23, 2005

The Open-Closed principle for software design

The Open-Closed principle states that the design of a software system should be open for extension, but individual classes should be closed for modification. This means that a software should be designed such that new functionality can be added by adding new classes, and by subclassing abstract classes that have already been defined. However once a class is implemented it should be closed for modifications.

Such a design can be achieved by using the "Program To An Interface" concept. This concept states that the client class must reference abstract classes instead of concrete classes. This way subclasses can be added to the system as new functionality is added, without breaking client code. Care must be taken so as not to instantiate concrete classes in the client code. The creation of concrete subclasses must be handled by object factories. The dependency inversion principle ensures proper implementation of the open-close principle.

To summarize: we must achieve extensibility in a software system by adding new classes (subclasses) and not by modifying existing classes.

Here is an example to better understand this principle.
Spec: We want to design a software which will play a selected tune on a selected musical instrument.
The system will have the following classes:
public class Tune {
}

public class Instrument {
public abstract void play(Tune tune);
}

public class Guitar extends Instrument {
public void play(Tune tune) {
//play the tune using a Guitar
}
}

public class Harmonium extends Instrument {
public void play(Tune tune) {
//play the tune using a Harmonium
}
}

The client code is the code which uses these objects and invokes the play method.
public class Jukebox {
public void playMusic() {
Tune tune = getUserSelectedTune();
Instrument instr = getUserSelectedInstrument();
instr.play(tune);
}
}

Notice that the client code (Jukebox) does not instantiate a particular instrument subclass. It simply gets the instrument (superclass) reference from a method that is responsible for creating a concrete instrument . If the specification changes and we wish to add more instruments in our system, all we have to do is create subclasses of Instrument, override the play method, and modify the method getUserSelectedInstrument(). The client code in Jukebox does not need to be changed. Incorporating the change in specification was easy and minimal code had to be touched because we used the open-closed principle.

Friday, November 18, 2005

Synchronizing static methods in Java threads

While teaching Java threads, a student asked me a very interesting question: When a thread calls a synchronized method of an object, it obtains the lock of the object, however how can a thread call a synchronized method that is static? An object may not even have been created when the static method is called.

To understand this better, let us look at a simple example of a class which contains two synchronized method: one static and one non-static.

public class SynchedClass {
public synchronized aMethod() {}
public static synchronized bMethod() {}
}

When a thread calls SynchedClass.bMethod(), it obtains a lock on the class java.lang.Class that represents the SynchedClass. Whenever the JVM loads a class it creates an instance of java.lang.Class which represents all objects of the loaded class. An instance of the class Class is created even before any object of that class is instantiated. When a synchronized static method is invoked the invoking thread obtains a lock to the class Class.
Note that if a thread calls a non-static synchronized method and obtains it's lock, another thread could concurrently call a static synchronized method of the same object, because they are locked on different objects.

Monday, September 26, 2005

Java Assignment - Milestone 6

Details for Milestone 6:

Create class Student which has the following characteristics:

Attributes:

String name;

String surname;

String id;

List course;

Methods:
Create getters/setters for the above attributes (including the course attribute).

public void addCourse(Course c) {
//This method should add the course to the list
}
public void deleteCourse(Course c) {
//This method should delete the specified course from the List of courses.
}

It is NOT necessary to write any test classes.

Tuesday, September 20, 2005

Java Assignment - Milestone 5

What a great way to communicate with students:
Here are the details for Milestone 5:
You have to create 3 classes -
Schedule.java
Course.java
CourseListProvider.java

Details for the classes are as follows.
Schedule.java contains attributes already discussed. Each attribute should have a getter and setter. You do NOT need to write a test class for Schedule.java

Course.java contains attributes already discussed. Each attribute should have a getter and setter. You do NOT need to write a test class for Course.java

CourseListProvider.java contains the following attributes and methods.
Attributes:
private List courses
public static final courseListDetailsFile="";
Methods:
public CourseListProvider() //constructer
private List buildCourseList()
This method will read the contents of the courselist.txt file and build Course objects. Each Course object will be associated with a schedule object to represent the schedule.

Thursday, June 09, 2005

Do Your Best

A very long time back I had read in a book: “Do your best and let god take care of the rest”. Sounds like a very simple line but if you think of it carefully it actually sums up the essence of how we must live our lives in just a few words. All of us have experienced times when we do not have any control over what happens. All we can do is try our very best and pray that events turn out in our favor. In such times it is very easy to fall prey to fatalism and think that all events in our lives are pre-destined.
But in reality it is not so. Ramana Maharishi used to say that the only control we have is over our reaction to events that happen to us. It is this reaction that sows the seeds of future events. If the reaction is positive, meaningful, and benign then it will pave the way for better future events. The Bhagwad Gita preaches: “Perform your duty in the best possible way and relinquish the fruits of your actions to god”. Applying this simple principle will help us lead meaningful, constructive lives, devoid of stress and tension. The importance of this principle in our professional life is also very significant. Stress is an occupational hazard for software professionals. We are constantly battling (often unrealistic) project deadlines. The stress is sometimes compounded by personal and health problems. How does one prevent stress from mounting.
The simplest way is to work for a company that believes in 40 hour weeks. But would that be fun? Probably not. The next best thing is to control stress at a personal level. Even when the entire team is going berserk, we can still remain calm, try our best, leave no stone unturned, and then just call it a day and let god take care of the rest. Do not mistake this for escapism. The idea is not to escape from work, but to understand that there is a point beyond which more effort becomes counter-productive. It actually causes loss of efficiency, productivity, and health.

Wednesday, June 08, 2005

Writing, does make you think

Yesterday I send an email to some friends about a particular Java feature. The original email read "JDK 1.5 has introduced a cool feature to allow overriden methods to have different return types". I had just read about this feature in a newsletter and decided to share it.
However just before clicking on the 'Send' button, I decided to review the mail to ensure that it was correctly phrased (I always have to review my first draft... even if it's just a line :-). While reading it again, I stopped at the word 'cool', and thought to myself - Is this a cool feature, or is it just a feature. Was the use of 'cool' appropriate here? This made me think a bit more about this feature. This feature was intended to remove the hassle of downcasting an object returned from a method. But wouldn't different return types for overriden methods break the "program to an interface" concept? Now the client code has to know the exact subclass that it is calling. Polymorphism is supposed to rid us of those long if...else statements, but to make use of this feature we will have to depend on them to tell us which subclass we have instantiated and are invoking a method of.
Now this feature does not look all that cool. Actually it seems that there is little purpose to this feature, except making the language more complex.
I was able to think this over because I decided to write about it... otherwise it still may have been a cool new feature for me. Offcourse it could still be a cool feature and I am open to a different perspective. But the point is that the process of writing helped me crystallize a concept which would not have happened otherwise.
Do drop in a note to tell me what you think about writing or about this new Java feature.

Thursday, May 26, 2005

Triple Quotes

I am sure everyone has heard of the terms single quote, and double quote, but have you heard of triple quote?
Yes such a term does exist, and it means three consecutive single or double quotes. So ‘’’ is a triple quote, and so is “””.

Tuesday, May 24, 2005

The Samurai Principle for Exception Handling

When a method fulfills it's responsibility, it is very clear what to return. We return the desired result object. However sometimes it is a bit unclear what to do when a method does not totally fulfill its responsibility. Do we return a null, do we return a partially populated object, or do we throw an Exception. Most of these situations can be resolved by applying the Samurai Principle - Return victorious, or not at all. If a function fulfills its responsibilities, return the appropiate result object, and if it doesn't then throw an Exception.
Can this principle have any exceptions? I cannot think of any at the moment. Do let me know if you come accross any.

Saturday, April 16, 2005

English Language Primer (contd.)

Continuing from yesterday... a bit about adjectives and adverbs

An adjective describes a noun. It usually follows the pattern "You are very _______________". For example "You are very misogynous", "You are very courageous", etc. Adjectives usually end in -ous, -ive, -as, -ed, -ic, etc.

Adverbs are generally formed by adding a -ly to an adjective. Misogynously, courageously, etc are adverbs.

Friday, April 15, 2005

An English Language Refresher

Today I have deviated a bit from the original category of my postings. From software programming languages to the english language. Very often while I find that I have forgotten the grammer priciples I learned in school. So I decided to revise them, and thought I'd share the refresher on my blog site. Here goes...
A noun is usually a thing. Nouns are preceded by words such as a, the, my, such, an, some. Some nouns are however difficult to identify. Words such as egoist, asceticism, and misogynist do not come accross as nouns right away. However if we put them in the context of a sentance... "... an egoist", "such asceticism...", "the misogynist...", then the above rule clearly identifies them as nouns. The confusion with these words is that at first glance they seem to be adjectives. "He is an egoist". Egoist is a description of a person 'He'. However because egoist is preceded with a 'an', it is a noun. This law is conistent if you think of sentances like "This is an apple", etc. Such nouns usually end in suffixes like -ness, -is, -ism, -y, -ion, etc.

A verb is usally an activity. It fits into the pattern, "Let us __________". A verb always has a counterpart which denotes the past tense. For example philander is a verb and it's past tense is philandered. Nouns on the other hand do not have a past tense. Verbs often end in suffixes like -ate, -ize, -fy, etc.

This primer will not help you in programming, but will probably help in creating better documentation. Remember software developement goes beyond mere programming :-)

Tuesday, March 01, 2005

Software Quality

Lately I have been following a lot of discussions on software code quality. There seems to be a lack of consensus on what quality means. This is not very surprising, since quality is a very subjective term, it means different things to different people. Here's what it means to me:
I believe every software is created for a specific purpose. The purpose usually defines the forces that act on the software. Most common forces that usually act on any software from a bsiness perspective are:
1. Adaptability - How well will the software adapt to changes
2. Reliability - How often will the software crash
3. Timeliness - How fast can we ship the software
4. Economy - How much will the software cost
5. Performance - Does the software have quick turnaround times
6. Scalability - Will the software continue to be performant if the user base were to increase substantially
7. Usability - How intuitive is it to use the software

These business factors are usually achieved by the following technical factors:
1. Architecture (Assuming OO design)
a. Choice of classes and their responsibilities
b. Coupling between classes
c. Usage of appropriate design patterns
d. Avoiding known anti patterns

2. Code quality
a. Adherence to coding standards
b. Choice of loops and conditionals
c. Algorithms
d. Size of methods (how large are the methods?)
e. Clarity of comments

3. Test coverage
a. Coverage of unit tests
b. Coverage of functional tests
c. Stress tests (for multi-user software)

4. The overall development process
a. Is the development process ad hoc or is it well outlined?
b. If it is well outlined then is it effective?
c. Code reviews
d. Build frequency
e. Processes each developer must follow locally before check-ins

Now let's consider each business factor and its relation with the technical factors.
Adaptability
1. Architecture
Software adaptability is usually achieved by the right selection of classes and loose coupling between them. This assumes knowledge of what is likely to change. However if we do not know aspects of the system that are likely to change then we could make a matrix of things that we think might change and associate a probability with change case. We can then address the high probability changes in the architecture.
Use of appropriate design patterns will be very useful.
2. Code Quality
We often have to refactor existing code when dealing with changes in business requirements. Two things are involved here. Identifying the code to change and understanding the implications of the change. Choice of appropriate class and method names, keeping methods small and meaningful, and clear comments play an important role in helping us identify code that needs to be refactored. Clear interactions among methods (non-spaghetti code?) will help us identify the implications of the change.
3. Test Coverage
Having a solid test harness will give us immediate feedback of the implication of refactoring.
4. The Overall Process
Regular code reviews ensure code quality, and adequate test coverage.

Reliability
1. Architecture
Architecture probably does not have an important role here.
2. Code Quality
Good coding practices like dealing with and recovering from Exceptions gracefully are very useful to ensure reliability.
3. Test Coverage
Adequate tests are very important to ensure reliability.
4. The overall design process
Again code reviews will help ensure adequate test coverage.

Timeliness
This is the tricky one. Let's say it is very important for a customer to deploy the software by a certain date and let us assume that the time is scarce. Before I write ahead, let me make it clear that making timeliness an important priority can be done only by sacrificing other factors. Whether the sacrifice is appropriate is discussed a few paragraphs ahead.
1. Architecture
Not overengineering the architecture will be useful. An overengineered architecture usually means more classes, and will result in a significantly greater effort on coding and writing test cases. In short do not plan for the future. Plan for the current scope, use best practices and go ahead.
2. Code Quality
We surely cannot achieve timeliness by skipping some methods. Assuming that we've got the write the code we've got to write, where can we save time? Perhaps in the thought process. Perhaps in commenting the code. I definiteky will not recommend saving time in the thought process. Commenting on the other hand is something where corners can be cut. Please do not wince at the thought of cutting corners. Atleast not here. We will discuss the concept very soon.
3. Test Coverage
We can produce software quickly if we write fewer test cases. But this has been known to cause more delays in the QA phase. However I sure there is a law of dimishing returns for test coverage - although I not sure where the curve starts flattening.
4. The Overall Process
Keeping the process light will defenitely help. Perhaps reducing the frequency of code reviews or even elliminating them might help.

Economy
1. Architecture
Is there any aspect in the architecture of a software that can help us achieve economy? Maybe this is slightly misplaced, but using open source frameworks or products may reduce costs. I say *may* reduce costs because we will first have to calculate the total cost of ownership of the open source software we intend to use before we can determine if it will really reduce costs. Some people may be thinking - but architecture should be generic - how did frameworks and open source products get here? Well from a practical perpective I am not sure if architecture can be truly generic. If we were making a web based application using Struts, then we will identify Action classes and ActionForm classes. The choice of these classes has been dictated by Struts. Were we using Turbine or Spring then we would have designed the application slightly differently. I strongly believe that the design of an application is infuenced by the choice of frameworks and other third party products.
Again keeping the architecture simple will help us reduce development costs.
2. Code Quality
Here economy translates into time spent on developing the software. The priciples we identified for timeliness apply here too.
3. Test Coverage
Here economy translates into time spent on developing the software. The priciples we identified for timeliness apply here too. Choice of open source testing frameworks might again help us. However it is important to evaluate their total cost of ownership first.
4. The Overall Process
Certain processes are heavy and also demand the use of expensive tools. I am not sure if there is any clear indication if using such processes and tools add value commensurate to the cost of the tools and other process elements. Again like in 'timeliness', using a light weight process with appropriate, but simple (and open source) tools can reduce the overall cost of developement.

Performance
1. Architecture
Here too I am not very sure if architecture plays a role. Perhaps it does. For example the choice of technology will determine performance. Using EJB's will be slower than using POJO's. But the speed can be enhanced by increasing the resources on the server. There are way too many factors that determine the performance of an application. Architecture cannot be linked with performance in any simplistic way.
2. Code Quality
Code quality is important for performance. We identified algorithms as part of code quality. Most applications have to iterate through object trees to produce an output. Apprpriate algorithms, and database queries play an important role in the overall performance of an application. Having said this I do agree with the widely held belief - "first make it work, then make it fast".
3. Test Coverage
Having appropriate stress tests will help us uncover areas which perform inadequaltely. Test suites will not elliminate performance problems, they will only help us identify them, which is better than the client identifying them.
4. The Overall Process
Again the overall process will contribute only in terms of ensuring proper test coverage. Code reviews might uncover obvious performance issues.

Friday, February 25, 2005

ROI on Architecture

Bill Venners has started an interesting thread on software architecture and ROI at Artima.
Here is my response to the posting:
There are two forces that a software usually has to reckon with. Changes in business requirements and changes in technology. Let's say we build an ERP system. Some business rules in the accounting module might have to be modified due to changes in tax laws. Parhaps the client might want to produce more reports or change some existing ones. The client might want to change the UI. Brainstorming with domain experts and clients will most likely help us make a comprehensive (though not all-encompassing) list of requirements that can change in the next let's say three years. With some further thought we may also be able to attach a probablity of change. If we incorporate enough flexibility for high probablity changes then we will get a good return on investment on the architecture. I think this is the middle ground between an overly simplified architecture and a very complex one. The other force that acts on our architecture is changes in technology. Had we created our ERP system with an amateuer homegrown MVC kernel, then we might at some point feel the need to use Struts or an equivalent framework. The refactoring effort will depend on our choices of classes and their responsibilities. If we have used good OO priciples and ensured that each class has a coherent set of responsibilities and the methods are well structured, then we might actually be able to reuse a large part of our existing code base with minor modifications in the new architecure. What if we have to face a drastic technological change, which will render our current code base useless? This is possible though not very likely. Technological changes do not usually happen overnight. There is enough indication before a promising technology becomes mainstream. If we adopt the practice of constant refactoring then we should be able to adapt to the new tecghnology gradually.I think there is a definite value to a well thought architecture. This value is maintained if the thought on architecture is not limited to the architecture phase, but rather is a continous process.Bill, you mention diminishing returns on code quality. How do you define code quality, and why does creating good quality code take more time? Good quality code is not bulkier than mediocre code. I think it is effort that is spent thinking on what to code, or how to structure code that is time consuming. If we constantly practice writing good code then this thought process becomes second nature, and it does not take a lot of time. The extra time it does take is worth more than the effort we would have to put in to fix bugs.Is it possible that if programmers had a lot of discipline and dilligence then they would produce good quality code by deault?

Thursday, February 10, 2005

Open Space Technology

A few days back I was reading Bruce Eckels blog on Open Spaces. Open Spaces seems to a very broad (open) ended concept, but it can be a very interesting and powerful concept if the participants are mature enough to make proper use of it. Here is the broad outline of my understanding of Open Spaces:
Open Spaces are conferences propelled by a concept or question. The driving concept could be anything from "How do we make our neighborhood cleaner" to "What is the best way to utilize web services". These are not preplanned conferences. The person or organization who wishes to explore a concept/problem will send out invitations in the community. People/companies who have similar interests will accept the invitation to attend. An invitation fee is usually charged to compensate for food, equipment, and conference room costs. The conference is a self organizing conference, which means there isn’t any pre-planned agenda. However the duration of the conference and time slot placeholders are pre-determined. The time slots are later filled with a concrete agenda. On the day of the conference the initiator gives a keynote presentation on the main issue, after which participants volunteer topics that they would like to explore under the main umbrella. Each participant who volunteers a discussion fills up a time slot and place. Those with similar interests also sign up. Note that all time slots and spaces may not be signed up for. More topics may emerge after the discussions start.
Once the self organizing agenda has been determined participants group up in various corners or wherever they want to and discuss the issue they signed up for. Participants may move around from one group to another or may stay with a group for the planned duration. The person who initiated a particular topic is responsible for maintaining the transcripts and documenting any interesting findings or observations. On the last day all conversations are consolidated by the lead participants (participants who initiated discussion topics) by briefly telling everyone what was discussed and any interesting findings that may have emerged. Important findings and insights are noted and may be published on a website or a technical journal for later reference.