Tuesday, October 27, 2015

Clean Code : Chapter 1

Image source


The author starts off (at this point repeating) by setting expectation that this will be a book filled with lots of code and it will make the reader a better programmer.
The author mocks at the notion of a future wherein all code would be auto-generated from specifications. I was very impressed by one of his statements wherein he says

    “code represents the details of the requirements”.

I think its very true. What we sometimes in our conversations on functional design brush off as “implementation detail” is actually THE specification realized as code. It is a very interesting perspective. But his next statement is a bit too opinionated and a bit incorrect I felt- he says 

“specifying requirements in such detail that a machine can execute them is programming”.

I don't think that's true. A machine just needs 1s and 0s to execute instructions, it is us (humans) who need code, be it high-level, low-level or assembly to maintain the software and build on it.                                                      
Next, the author in many different ways discusses the consequences of bad code. He mentions the ill fate of a software company that had created a massively popular product but could not maintain it well i.e. keep bugs under control and continue to innovate. A situation most of us would have run into is needing to make a feature, but using hacks. More often, we tend to forget about this mess until the next person needs to deal with it. The author talks about how feature development is quick at the start of a project and how it limps along as code grows and finally comes to a grinding halt. Management decisions to throw more people at the problem just does not help the cause
Eventually, it is the programmer who should take blame for bad code irrelevant of what “forced” him/her to do that. It is on the person who writes code to set expectations with business/management/marketing etc that innovation/features will happen only if clean code happens.
The author then acknowledges that it takes time, hard work and practice for a programmer to acquire the ability to write clean code / refactor bad code.
The author then presents the view-points of a few experienced and respected programmers and their take on clean code. Here is the bullet list of things from the different folk.
Clean code is:
- readable — minimal explicitly defined dependencies, clear concise API
- straightforward
- optimal enough
- modular and each module does one thing well
- has error handling and tests
Finally the author wraps up by saying that the rest of the book basically is his version of what clean code is. He encourages the reader to understand the perspectives and opinions presented but to also form their own/explore other schools of thought as time passes.
Lastly he ends with this really nice quote
“Leave the campground cleaner than you found it”

Effective Java - Item 6 : Eliminate obsolete object references

Before we jump into the item let us look at a very important feature offered by Java, garbage collection. 
Basically garbage collection in Java does the job of free() in C and delete() in C++. But unlike C and C++, garbage collection is done automatically in Java. The garbage collector will look for objects which are no longer being used by the program and gets rid of them thus freeing the memory so that it can be allocated to new objects.

So what exactly is an obsolete reference?
It is simply a reference which will never be dereferenced again i.e. it will be kept around in the memory though it will never be used, preventing the object it refers to from being eligible for garbage collection. And if an unused object is not garbage collected it causes a memory leak.

So how do we avoid them?
The author gives a very good example of a simple stack implementation to explain where obsolete references can be created and how to avoid creating them.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Stack {
 private Object[] elements;
 private int size = 0;
 private static final int DEFAULT_INITIAL_CAPACITY = 16;
 
 public Stack() {
  elements = new Object[DEFAULT_INITIAL_CAPACITY];
 }
 
 public void push(Object e) {
  ensureCapacity();
  elements[size++] = e;
 }
 
 public Object pop() {
  if (size == 0)
   throw new EmptyStackException();
  return elements[--size];
 }
 
 /**
 * Ensure space for at least one more element, roughly
 * doubling the capacity each time the array needs to grow.
 */
 private void ensureCapacity() {
  if (elements.length == size)
  elements = Arrays.copyOf(elements, 2 * size + 1);
 }
}
The above code works perfectly well, but there is a memory leak present. Whenever we want to push an element to the stack we create and pass an object reference to the push() function, but when we pop an element we are just returning the topmost object in the elements array and reducing the size of the stack. The object reference will still be present in the array but will never be used again since it is popped out of the stack thus creating an obsolete reference.

In order to fix this problem the author suggests using the basic method to dereference an object i.e. by nulling the reference. So the modified pop function should look like this
1
2
3
4
5
6
7
public Object pop() {
 if (size == 0)
  throw new EmptyStackException();
 Object result = elements[--size];
 elements[size] = null; // Eliminate obsolete reference
 return result;
}

Another scenario where memory leaks can happen is when we use caches. A cache is an area of local memory that holds a copy of frequently accessed data that is otherwise expensive to get or compute, e.g.: A result of a query to a database or a disk file.
Here is a good resource I found on how to create a simple in-memory cache in Java.
The author tells that it is common for programmers to put object references into a cache and forget about it and leave it there long after it becomes irrelevant. So as a solution he suggests using WeakHashMap to implement a cache. It is an implementation of Map with keys which are weak references i.e. a key/value mapping is removed when the key is no longer referenced.
Another solution the author suggests is to clear the cache periodically by a background thread or as a side effect of adding new entries to the cache.

Now let us look at a third scenario where memory leaks can happen because of obsolete references. Say that I have an object A, which calls object B to perform some database update. Once B's function completes it calls a callback function in A. So now B remains in memory until A completes, creating a memory leak. So as a solution we can explicitly deregister for the callback and remove the reference of B in the class A. Something like this :
1
2
b.removeListener(this);
b = null;
This will ensure that the JVM will be informed that no references exists to class B and garbage collector will remove it from the memory.

The author concludes by telling that memory leaks are not very easily noticed as they do not show up as obvious failures so it is always good to know where they occur commonly and avoid them in the first place.

Wednesday, October 21, 2015

Effective Java - Item 5 : Avoid creating unnecessary objects

Whenever I had to create a string I always had the confusion of doing it either this way
String message = new String("hello world");
or this way
String message = "hello world";
Programatically both are correct but one of them is better than the other. Let us look at which one.

The first method creates a new String object in the heap whenever it is executed. But what we are passing as an argument to to the constructor of String class to create the object is itself an instance of String class.
The second method will create an instance of String in a section of the heap known as String constant pool.
Now if both of the above lines are executed for a second time the first line will create a new String object on the heap but the second line will reuse the object it created the first time from the String constant pool. It might help you to understand it visually to remember it for a longer time.

So the second method is a better option since it does not create new instances and crowd the heap needlessly. 
This was the case with immutable objects like String. We can also avoid creating unnecessary objects and reuse in case of some mutable objects too. Let us look at an example.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class Commodity {

 private final Date manufactureDate;
 private final int validity;
 
 public boolean isExpired(){
  Calendar gmtCal =
    Calendar.getInstance(TimeZone.getTimeZone("GMT"));
  Date today = gmtCal.getTime();
  gmtCal.setTime(this.manufactureDate);
  gmtCal.add(Calendar.MONTH, this.validity);
  Date expiryDate = gmtCal.getTime();
  
  return expiryDate.compareTo(today) > 0;
 }
}

Here the method isExpired creates the Calendar and Date objects each time it is invoked. These are very expensive objects to create. So how can we avoid this? 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class Commodity {

 private final Date manufactureDate;
 private final int validity;
 private static final Calendar gmtCal;
 private static final Date today;
 
 static {
  gmtCal =
    Calendar.getInstance(TimeZone.getTimeZone("GMT"));
  today = gmtCal.getTime();
 }
 
 public boolean isExpired(){
  gmtCal.setTime(this.manufactureDate);
  gmtCal.add(Calendar.MONTH, this.validity);
  Date expiryDate = gmtCal.getTime();
  
  return expiryDate.compareTo(today) > 0; 
 }
}
So here as an improvisation we can include the expensive object creation code in a static block so that it will be invoked only once when it is initialized and not each time the method is invoked.
Apart from achieving a significant gain in performance it also makes the code better organized and understandable.

Another instance where we usually create unnecessary objects is places where we use boxed primitives instead of primitive types
1
2
3
4
5
6
7
public static void main(String[] args) {
   Long sum = 0L;
   for (long i = 0; i < Integer.MAX_VALUE; i++)  {
     sum += i;
   }
   System.out.println(sum);
}
The above code segment calculates the sum of all positive int values. The variable sum is declared as a Long but inside the for loop it is being assigned a primitive value long. This is supported in Java by means of autoboxing. So this creates a lot of  unnecessary Long objects which increases the runtime. Thus it is always better to prefer primitive types.

After looking at the above instances you might wonder if object creation in general is a very bad thing to do. Well, it is not the case. The author makes sure to clarify that only creating unnecessary objects (especially when dealing with heavyweight objects e.g. database connection objects) should be avoided. 

Thursday, October 15, 2015

Clean code : Introduction

Clean code is hard work
Here the author talks about how the content is structured and the reasons for it.
At a high level, there are 3 parts to it. The first part imparts the knowledge i.e, the principles, practices that a programmer needs to be aware of. The second part has case studies which involves work on the reader's part to carefully understand code, identify issues and refactor it. The third part captures the learning acquired through the hands-on as heuristics.
The justification for this structure of the book's material is that it is not enough for the programmer to be just informed of good practices and principles, which would be akin to telling you the theory of riding a bike which is fine but would not prevent you from falling the first time you get on one.
The author sets expectations that the reader should be prepared to work hard(esp the second part with the case studies) and read a lot of code.
Wow, that's three chapters before the actual material even starts. I cannot wait to start..

Wednesday, October 14, 2015

Clean code : Getting started

Reading the foreword chapter of this book was an experience in itself. It appears that the person who has written the foreword — James is a buddy of the author whom he refers to as Bob.

He compares software development to the automobile industry. He stresses on the reality that more time/resource is spent on the maintenance than on actual production. He briefly describes some foundational principles of a methodology known as Total Productive Maintenence (TPM) that has its origins in the Japanese auto manufacturing industry. He relates these principles to coding practices. 

These principles are known as 5S:
  • Seiri or organization. Eg. Variable names
  • Seiton or tidiness. Eg. A piece of code should be where you expect to find it else it should be refactored
  • Seiso or cleaning. Eg. Remove extraneous comments and dead/commented code 
  • Seiketsu or standardization. Eg. Team-wide consistent coding styles
  • Shutsuke or discipline. Eg. Continuous self improvement 

The author acknowledges and appreciates that such philosophies as above are inculcated into the wisdom of most cultures and not just Japanese. He recognizes the importance of software development practices to lean upon these time-tested beliefs. He stresses on attention to detail, being honest to self. He mentions that the agile methodology encourages the honesty aspect by helping teams know about the current state of things on a regular basis. He ensures that the reader understands the importance of revisiting code to re-factor to make it better.

Tuesday, October 13, 2015

Clean Code : Learning to code better

As I am preparing for technical interviews, I often puzzle over the importance of learning about coding best practices/patterns. With just a few years of professional programming experience, I guess I find it a bit hard to understand what an interviewer's expectations are, in this area. All that said, I realized it would not hurt to start learning these topics irrespective of interview preparation.


I was recommended this book Robert Martin’s Clean Code by one of my graduate school professors. The book promises to be an engaging reading experience. As I work my way through it, I will make notes, capture my impressions in the form of blog articles. In a way, writing about things that I am learning new helps me maintain focus because I feel compelled to understand concepts thoroughly and present them in an easy to follow format.

P.S. This series of blog articles will continue along with my reading of Effective Java.