Sunday, September 8, 2019

Basics to Understand Modern Infrastructure


When discussing modern infrastructure or cloud infrastructure lots of terms are tossed around like virtualization, container, docker, etc. While it is not essential for everyone to understand these in detail, a basic/fundamental understanding/view is becoming essential for those who are  in the field of software development.

In fact, even a lot of people who may already use one or more of these, may still have some "vagueness" when it comes to explaining them to others. So, I wanted to capture some quick points which helped me have a high level  understanding of these. These may not be 100% technically correct, but should help the aforementioned purpose.

Virtualization / Virtual Machine (VM)

This once is fairly straight forward and most of us have a clear view on this. We have a physical machine with certain resources. Slicing this into multiple machines virtually is called virtualization. The OS running on these machines will see them as a physical machine. By the way, the physical machine is referred as the metal or bare metal servers. Sometimes they are also referred as host machines. The slices are called virtual machines or VMs.

Vagrant

When slicing the physical machine into multiple into virtual ones, we need to provide the definition, including its software configuration, for each of these machines. As multiple virtualization tools came up, there was a need to create this definition that was not tied to a specific tool. Vagrant is a tool that fills that need. Create the definition as a vagrant definition and use that definition to run the VM and the software setup on any virtualization tool.
Container and Docker

A container is actually a combination features of Linux kernel which provide an isolation to a group of processes. For this reason they are also called as OS level virtualization. While the features required for this like cgroups and namespace isolation are available at the OS level, container tools offer them as a bundle, hiding the details. See LXC

Docker is a tool that helps to define such containers with a specific run time like OS etc. and then run them by leveraging the container features of Linux. See here for more details and technically correct information.

Kubernetes
Kubernetes (you would see this also referred as k8s) is a container orchestration platform. Instead of dealing with individual containers, Kubernetes deals with what's called a Pod, that represent the group of resources for an application. It then manages them by scaling the number of instances, choosing the node to run them, monitor, restart etc. See here for more information.

Thursday, August 29, 2019

Starter Toolkit for Programming Beginners

One of the things that is going on in my mind for a while was creating a quick guide on the toolkit for programming beginners. When I say toolkit, I don't mean the tools like IDE etc., but rather the skills and nuances that are mostly learnt on the job, assuming that we get to have a good mentor. It is not uncommon for even programmers with enough experience in the industry not getting a chance to acquire these skills.

Some of the Gen Y/Z kids may have got some insight into some of these aspects, thanks to the active opensource communities. But, still collating these in one place so that they get a view or an introduction to most of these by the time to get into full-time programming.

I am planning to expand on each of these topics, as the time permits and would be linking to the blog article as I write them.

Here is the inventory of items that are part of the tool kit, with predominant focus on model web applications and mobile apps:

  • Understanding of the networking involved - the client browser to multiple servers where different pieces even seeming simple websites exist, the overwhelming TLAs invented to scare the new comers, etc.
  • Understanding what happens in the server and what happens in the client (the web and mobile)
  • Security - What are the basics to know and modern security concepts
  • Source control or version control - How to protect your work from getting lost
  • Refactoring - The art of routing maintenance of the code you write 
  • Debugging anything
  • Scripting tools a.k.a. Automating boring work
  • *nix Basics - Programmers paradise

Monday, October 30, 2017

Refactoring Code

I believe refactoring is a very important trait for a programmer. Refactoring helps in reducing the repetition of code and also helps to make the code generic. Like everything else in life, code too accumulates dust if not maintained constantly. Constant refactoring helps in keeping the code clean. Learning to refactor early on in programming career helps in having a great career. In fact it is something we don't even need to learn as, as human beings we are experts at identifying patterns and  crux of refactoring is pattern matching.

Recently I was reminded of the age old programming puzzle by a friend and wanted to use that to capture my thoughts on refactoring.

The code is to generate something like this:



The initial code we would typically write would be specific to this particular output . (See the initial iteration in JSBin)




The first thing that strikes from this code is the repetition of the code block within the two for loops. The first refactor will be to extract this into a function. 

Anytime we see code being repeated, it immediately calls for refactoring. It is well known that lesser the code lesser will be the defects. 

The refactored code could look like this: (1st round of refactor)

This is still specific to the particular output. It could further be refactored to be generic, suitable for output of similar pattern, say a grid of 15x15. (2nd Round - Generalization)


Still it provides the same output as the first code, but, in a much generic way, with less repetition. 

The key rules of refactoring:

#1: If there is repetition of code, it is a no brainer for refactoring

#2: If the code could be applicable for similar problems, refactor it to be generic. Just be aware of the ROTI (Return on time invested)

#3: Don't make the code clever in the name of refactoring. The code should be clear to understand. Not clever. This code could be refactored to use a single loop, but, at the cost of clarity.   See line 24 in the code below. (This is fairly straight forward than the clever codes out in the wild. But, you get the drift.)


(Have a look at http://jsbin.com/bemitew/edit?html,js,output which has this 1 loop implementation)

Happy refactoring!




Monday, March 13, 2017

Installing QBasic on Mac a.k.a Revisiting the school days

My daughter recently needed QBasic for her school work. I set out to install the exact same program in my Mac as online emulators did not do a great job without confusing her.

The ingredients:

  • Oracle VirtualBox
  • FreeDos
  • olddos.exe
Recipe:

  • Installed Oracle VirtualBox
  • Installed FreeDos using (http://wiki.freedos.org/wiki/index.php/VirtualBox), along with networking
  • Created a ISO image with olddos.exe ( https://web.archive.org/web/20070316205657/http://download.microsoft.com/download/win95upg/tool_s/1.0/w95/en-us/olddos.exe )
    • Used DiskUtility and created a new image (Be sure to choose image format as CD/DVD Master)
    • Copies the olddos.exe to the image
    • Used the following command from terminal to convert the CDR to ISO
hdiutil makehybrid -iso -joliet -o DosUtil.iso DosUtil.cdr

  • Mounted the ISO in VirtualBox as  a drive
  • Ran the self extracting archive olddos.exe
Now QBasic is all hot and steaming and ready to be served.

Monday, July 8, 2013

Dispatcher Servlet to turn off handler stopping at semicolon


 import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.context.ApplicationContext; 

public class MyDispatcherServlet extends DispatcherServlet {
    @Override
    protected void initStrategies(ApplicationContext context) {
        super.initStrategies(context);
        for (AbstractHandlerMapping handlerMapping : BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, AbstractHandlerMapping.class, true, false).values()) {

            handlerMapping.setRemoveSemicolonContent(false);
        }
    }

}

Wednesday, April 17, 2013

My Ordeal with Samsung S2 JB Upgrade (Has happy ending)

I have been waiting for the JB upgrade for my GT-I9100G for quite sometime. It is phone bought in India and the update has been rolling out gradually in the past weeks for S2 s in India. I was clicking on the "Check for updates" button everyday, in the hopes of getting the update even though I had enabled automatic update check.

Last Friday, I was very happy to see my screen popup with the information that the update has been found and downloaded and prompted me to install or later. Usually I make sure that the battery power is almost full and then initiate the update. But, this time my excitement overtook my caution and I clicked on "Install". I immediately plugged in my phone into the power socket and waiting for the update to complete. It seemed to be running fine, but suddenly after the automatic reboot, it had got stuck in the boot screen. I waited for quite sometime before I realized that my phone has been "soft-bricked".

I had also not backed up some of my data in my excitement and my ordeal began. My tasks were to:
1. Get the data from the internal SD out
2. Update to JB

I tried entering into the Android recovery mode  (Volume up + Power + Home) hoping it to be helpful. It did not help much with respect to getting the update work. Then after searching the net for a while I could get the required tools for data recovery and update. All the information is out there, but, I felt they were are not in a single place.

The first step was to get to a better recovery mode of ClockWorkMod. To install this, I did the following steps:

1. Odin307.zip  - http://forum.xda-developers.com/showthread.php?t=1738841
2. Installed CWM for recovery mode -
a. GT-I9100G_Blazing_Kernel_v3_CWM5.Tar from http://www.androidfilehost.com/?fid=9390288116658474142
       b. Used Odin to install this Kernel. The instructions are commonly available:


  1. Turn off you phone and enter Download or Odin mode: press and hold Volume Down + Home + Power buttons together for a few seconds.
  2. You will  see a screen asking you to press the Volume Up button. Press it and you will enter the download mode.
  3. Launch Odin
  4. Connect your phone to the computer via USB cable and wait till Odin detects your device. A successful connection is indicated by the ID:COM port turning blue and “Added!!” text at the message box below.
  5. Make sure that only the “Auto Reboot” and “F Reset Time” options are checked on Odin. 
3. Launched the CWM recovery mode by using volume up+ power + home buttons. 
4. Used CWM backup to SD card to create back of phone's system storage. - This back up contains phone logs, SMS and contacts.
5. Use the CWM mounts menu item to mount internal storage (sometimes referred as internal SD) of the phone. It was called as emmc for me. (Some people have mentioned that their internal storage was called as sdcard and external as emmc)
6. Connect the USB cable and use "adb pull" (Android developer tools) get the files in emmc 
7. The contacts will be available in data\data\com.android.providers.contacts\databases directory of data.ext4 zip file in the CWM back up created in step 4. Use the script from https://github.com/stachre/dump-contacts2db to convert contacts2.db to VCF which could be imported into Android. I used a Ubuntu running on a Sun VirtualBox to execute the script. Use the following command in Ubuntu to install required dependencies for the script. 
sudo apt-get install sqlite3 libsqlite3-dev.
8. SMS are available in data\data\com.android.providers.telephony\databases\mmssms.db. Used yaffs-mmssmsdb-calls-extractor.zip to get the SMS from backup to the XML  format used by the "SMS back & restore" android application, which could be imported. The application can directly work on mmssms.db. 
9. Now the back ups are complete. The next is to install the JB. The official Samsung JB build is available from http://www.sammobile.com/firmwares/1/?model=GT-I9100G&pcode=INU#firmware for India model of GT-I9100G. 
10. Then use Odin to write the firmware
11. Restore contacts and SMS. Use import menu in contacts to restore VCF. Use SMS back &  restore for importing back the SMS.  



At last the S2 was back in business.

Thursday, April 11, 2013

File download page using Spring


In web.xml, map directory listing URL to spring dispatcher:


 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>*.html</url-pattern>
 </servlet-mapping>

 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>/download/*</url-pattern>
 </servlet-mapping>

The first one is your existing dispatcher and the second one for download.

In spring security configuration set up appropriate configuration:
<intercept-url pattern="/download/**" access="permitAll" />

In Spring servlet config xml set this up to make path configurable:

 <bean id="appPropertiesBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="singleton" value="true" />
  <property name="properties">
   <props>
    <prop key="downloadPath">C:/</prop>
   </props>
  </property>
 </bean>

In your controller for the path property:

    @Value("#{appPropertiesBean.downloadPath}")
    private File downloadPath;

In controller add methods to generate directory listing:

   @RequestMapping(value = "/files/**", method = RequestMethod.GET)

    public ModelAndView archiveDirectoryListing(HttpServletRequest request, HttpServletResponse response) {
        try {
            //String restOfTheUrl=(String)request.getAttribute( HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE );
            //The above line seems to cause issues with filenames 
            // containing semicolon. Use the below line instead
            String restOfTheUrl=request.getPathInfo();
            restOfTheUrl=restOfTheUrl.substring("/files".length());
            File physicalFileRequested=new File(downloadPath,restOfTheUrl);
            System.out.println("Accessing .." + physicalFileRequested);
            if (!physicalFileRequested.getCanonicalPath().startsWith(archivePath.getCanonicalPath())) { //Requester is trying to go above the archive directory
         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
         return;
            }
            if (!physicalFileRequested.exists()) {
         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
         return;       
            }         
            System.out.println("Access allowed " + physicalFileRequested);
            System.out.println("Access allowed " + physicalFileRequested.isFile());
            System.out.println("Access allowed " + physicalFileRequested.isDirectory());
            System.out.println("Rest of url : " + restOfTheUrl);
            if (physicalFileRequested.isFile()) {
         System.out.println("Accessing file:" + physicalFileRequested);
         streamFile(physicalFileRequested,response);
            } else if (physicalFileRequested.isDirectory()){
         if (! restOfTheUrl.endsWith("/")) {
             response.sendRedirect(request.getContextPath() + "/download/files" + restOfTheUrl + "/");
         }
         System.out.println("Accessing dir:" + physicalFileRequested);
         generateDirectoryListing(physicalFileRequested,response);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Error accessing requested file/directory.");
        }
    }

    private void streamFile(File physicalFileRequested, HttpServletResponse response) {
 try {
     response.setContentType("application/pdf");
     // get your file as InputStream
     InputStream is = new FileInputStream(physicalFileRequested);
     // copy it to response's OutputStream
     IOUtils.copy(is, response.getOutputStream());
     response.flushBuffer();
 } catch (IOException ex) {
     throw new RuntimeException("Error accessing requested file/directory.");
 }
    }

    private void generateDirectoryListing(File physicalFileRequested, HttpServletResponse response) {
 try {
     StringBuilder sb=new StringBuilder();
     sb.append("<html>");
     sb.append("<body>");
     sb.append("<a href='..'>..</a><br>");

     File [] childFiles=physicalFileRequested.listFiles();
     for (File childFile:childFiles) {
  String relativePath = childFile.getName();
   sb.append("<a href='"+ URLEncoder.encode(relativePath,"UTF-8")  + "'>" +relativePath+"</a><br>");
     } 
     sb.append("</body>");
     sb.append("</html>");
    response.getWriter().print(sb.toString());
 } catch (Exception e) {
     throw new RuntimeException("Error accessing requested file/directory.");
 }
    }



Download URL will be like:

http://localhost:9090/context/download/files/

Alternatively, the directory listing HTML could be generated using a view, by using the following alternate implementation of the method (Note: wherever null is returned for ModelAndView, Spring assumes that response has already been handled and no view redirection needs to happen):


   @RequestMapping(value = "/files/**", method = RequestMethod.GET)
    public ModelAndView archiveDirectoryListing(HttpServletRequest request, HttpServletResponse response) {
        try {
            String restOfTheUrl=(String)request.getAttribute( HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE );
            restOfTheUrl=restOfTheUrl.substring("/files".length());
            File physicalFileRequested=new File(archivePath,restOfTheUrl);
            System.out.println("Accessing .." + physicalFileRequested);
            if (!physicalFileRequested.getCanonicalPath().startsWith(archivePath.getCanonicalPath())) { //Requester is trying to go above the archive directory
         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
         return null;
            }
            if (!physicalFileRequested.exists()) {
         response.setStatus(HttpServletResponse.SC_NOT_FOUND);
         return null;         
            }           
            if (physicalFileRequested.isFile()) {
         streamFile(physicalFileRequested,response);
         return null;
            } else if (physicalFileRequested.isDirectory()){
         if (! restOfTheUrl.endsWith("/")) {
             response.sendRedirect(request.getContextPath() + "/archive/files" + restOfTheUrl + "/");
         }
         System.out.println("Accessing dir:" + physicalFileRequested);
         ModelAndView modelAndView=new ModelAndView("direcoryListing");
         modelAndView.addObject("fileList", physicalFileRequested.listFiles());
         return modelAndView;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Error accessing requested file/directory.");
        }
 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
 return null;         
    }


And a freemarker view, direcoryListing.ftl:

<html>
<body>
<h1>Welcome to the download page</h1>
<a href='..'>..</a><br>
<#list fileList as file>
<a href='${file.name}'> ${file.name}</a><br>
</#list>
</body>
</html>

Configure freemarker in application context:

<!-- freemarker config -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/pages/" />
</bean>           
<!-- View resolvers can also be configured with ResourceBundles or XML files. 
If you need different view resolving based on Locale, you have to use the 
resource bundle resolver. -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="suffix" value=".ftl" />
</bean>

Monday, April 8, 2013

Tiles Boardgame

During my college days I was introduced to a board game. We used to play that in the breaks, by drawing the board on paper and using two different pens to differentiate the players' pieces.

The board game is a two player game and like tic-tac-toe, but of a larger size. The board is typically a 7x7 square. The goal is for a player to occupy 4 contiguous boxes in the board, either horizontally, vertically or diagonally.

One day, in my friend Jerine's home, we were test driving VB for the first time and we decided to build this game using VB. In a few hours we had the VB implementation of the game with a very basic computer opponent. It was fun and we did not think about it much after then.

In a sudden rush of nostalgia I thought of implementing that in JS. It is now available in Google code http://tiles-game.googlecode.com Github https://github.com/kkleokrish/tiles-game. The core of the game is in Tiles.js and the HTML files are rudimentary UI on top that, just to visualize the functionality.

Saturday, January 21, 2012

Weird coincidences

There are a few instances of weird coincidences that I vividly remember which I wanted to record in the blog for past few months. Following are two such instances:

Catalytic Converter

It was during my school days when we started studying organic chemistry and about catalysts. Few of the reactions involved, conversion of hydrocarbons into carbon monoxide carbon dioxide and water etc.

At the same time we were introduced pollutants, carbon monoxide, NOx etc. I used to correlate and think that if we could convert CO to CO2 and NOx to N2 and water, we could reduce pollution. If they could be done in the exhaust of the cars we could eliminate air pollution in vehicles. Applying what we read, this may need catalysts.

I discussed this at length with my cousin during a week end. The Hindu used to carry a supplement on Thurdays for Science and Technology. The Thursday after that weekend, there was an article in that about catalytic converters. It discussed about beehive shaped compartments which would have catalysts to convert CO to CO2 etc. to reduce pollution.

I did not realize it then, but, it is such a weird coincidence looking back now.

Vertical Farming

This is more recent and happened in the last year or so. I kept thinking about the reducing agricultural lands in India and thought that if we could do farming in multi-stories, then potentially we could produce more in limited space. Each locality could have one such building. This would supply a part of the needs for the locality. It should not be a glass house so that it could be maintained easily, but instead lighting could be through mirrors sending the sunlight into the building or optical fibers running from the terrace. Neither of these might be economically feasible, but just a thought. I thought this could be called vertical farming.

The day after that there was an article in The Times of India, that discussed about an expert who was working on agriculture in increasingly urban set up and he mentioned about multi-storey agriculture and called it Vertical Farming. This is second weird coincidence and made me think about recording these in a blog.

Saturday, May 7, 2011

I have a dream ...

роХро╡ро▓ைроХро│் роЗро▓்ро▓ா роЙро▒роХ்роХроо் - роЕродிро▓்
роЗрой்рокроЩ்роХро│் роиிро▒ைрои்род роХройро╡ு
рокроЪுрооைроХро│் роиிро▒ைрои்род роиிро▓роЩ்роХро│் - роЕродிро▓்
роЪிро▓்ро▓ெрой роУроЯுроо் роУроЯை
рооро░роЩ்роХро│் роиிро▒ைрои்род ро╡ройроо் - роЕродிро▓்
роиிро▒்роХாродிроЪைроХ்роХுроо் роХுропிро▓்роХро│்
ро╡ேроЯ்роЯை роЖроЯா рокுро▓ிроХро│் - роЕродройாро▓்
рокропрооிрой்ро▒ி роЙро▓ро╡ுроо் рооாрой்роХро│்
рооாроЪро▒்ро▒ родெрой்ро▒ро▓் роХாро▒்ро▒ு - роЕродிро▓்
роЗройிрооை роиிро▒ைрои்род роХீродроо்
роХைроХ்роХெроЯ்роЯுроо் роЙропро░роо் рокро┤роЩ்роХро│் - роЕродிро▓்
родிрой்ройрод் родெро╡ிроЯ்роЯா роЪுро╡ைроХро│்
рокாроп்рои்родு роЪிродро▒ுроо் роЕро░ுро╡ிроХро│் - роЕро╡ை
рокிро▒рои்родு ро╡рои்род рооுроХроЯுроХро│்
роЕрооைродிропாроХ роУроЯுроо் роиродி - роЕродிро▓்
рокாроп்рои்родு роиீрои்родுроо் рооீрой்роХро│்
рокройி рокроЯро░்рои்род рокுро▓்ро╡ெро│ி - роЕродிро▓்
рооேроп்роХிрой்ро▒ роЖроЯு рооாроЯு
родேроЩ்роХி роиிро▒்роХுроо் родрог்рогீро░் - роЕродிро▓்
роХுроЯ்роЯிропோроЯு роХுро│ிроХ்роХுроо் ропாройை
родேро╡ை ропுрод்родроЩ்роХро│் роЕро▒்ро▒ рокூрооி
рооройிродро░்роХро│் роЕро▒்ро▒ родீро╡ு - роЕродிро▓்
родройிрооைропிро▓் роиாрой்

Conversation with God

роХроЯро╡ுро│்

роОрой் рооீродு роОрой்ройроЯா роХோрокроо் роЙройроХ்роХு?
роЪொро▓்ро▓ாрооро▓் ро╡ாроп் роЕроЯைрод்родு рокோройாроп் роОродро▒்роХு?
роХோрокрооா? родாрокрооா? ро╡ேроХрооா? роЪрои்родேроХрооா?
роиீ роЪெроп்род родро╡ро▒ுроХ்роХு родрог்роЯройை роОройроХ்роХு

рооாро▒்ро▒ாройோроЯு роиீ рокேроЪிроЪ் роЪிро░ிрод்родு роХுро▓ாро╡ுроХைропிро▓்
роОрой் рооройроо் рокродைроХ்роХுродே роОрой்ройெрой்ро▒ு роиாрой் роЪொро▓்ро╡ேрой்?
роиாро│் родோро▒ுроо் роХுро▒்ро▒ роЙрогро░்роЪ்роЪிропிро▓ே ро╡ெрои்родு роиாрой் роороЯிроХிрой்ро▒ேрой்
роЗрод்родрог்роЯройропை роОройроХ்роХро│ிрод்родு
роОрой்рой роиீ роХрог்роЯாропோ роЪொро▓்?
-роЗродு рооройிродрой்

роЪிройроо் роХொрог்роЯு роЪீро▒ுро╡родுроо் рооройிродрок் рокрог்рокே!
ро╡ாроп் роУропாрооро▓் рокேроЪுро╡родுроо் рооройிродрок் рокрог்рокே!
роХோрокрооுроо் родாрокрооுроо் рооройிродрок் рокрог்рокே!
роЪрои்родேроХрок் рокேроп் роЕродுро╡ுроо் рооройிродрок் рокрог்рокே!

роЙрой்ройை рокроЯைрод்родродை родро╡ро▒ெрой்ро▒ாроп் рооройிродா!
рокроЯைроХ்роХрок் рокроЯ்роЯродிрой் роЪுроХрооро▒ிро╡ாропா?
ро╡ாро┤்роХ்роХைропை родрог்роЯройை роОрой்ро▒ே роЪொрой்рой роиீ
роЕро┤роХாрой ро░ோроЬாро╡ிрой் рооுро│்ро│ро▒ிро╡ாропா?
рооாро▒்ро▒ாройோроЯு роХுро▓ாро╡ுроХிро▒ேрой் роОрой்ро▒ роиீ
роЗроХ்роХро░ைроХ்роХு роЕроХ்роХро░ை рокроЪ்роЪை роОрой்ро▒ро▒ிро╡ாропா?
роХுро▒்ро▒ роЙрогро░்роЪ்роЪிропிро▓ே роороЯிроХிро▒ேрой் роОрой்ро▒ роиீ - роЕродு
роХுро▒்ро▒роо் рокுро░ிрои்родோро░ிрой் роЙроЯைрооை роОрой்ро▒ро▒ிро╡ாропா?
ро╡ாро┤்роХை роТро░ு ро░ோроЬா - роЕродை
роЗро░роЪிроХ்роХроХ் роХро▒்ро▒ுроХொро│்.
рокுро▓роо்рокி роОрой்ройிроЯроо் ро╡рои்родு роЕро┤ுродு рокропройிро▓்ро▓ை
ро╡ாро┤்роХைропிро▓ே роОрой்ро▒ுроо் роиீ роХроЯிройрооாроп் роЙро┤ைрод்родிроЯ்роЯாро▓் роЙрой்
роХроЯிрой роЙро┤ைрок்рокிройிро▓ே рокெро░ுроо் рокроХுродி роиாрой் роЪுроорок்рокேрой்
ро╡ாро┤்роХை роТро░ு рокроЮ்роЪு рооெрод்родை
роЕродை роЪுроХிроХ்роХ роХро▒்ро▒ுроХ்роХொро│்.
роЕродிро▓் родுрой்рокроЩ்роХро│் роЪிро▒ு роХро▒்роХро│்
роЕродை роЕроХро▒்ро▒роХ் роХро▒்ро▒ுроХ்роХொро│்.


ро╡ாро┤்роХ்роХை роТро░ு родெрой்ро▒ро▓்
роЕродை роЪுро╡ாроЪிроХ்роХроХ் роХро▒்ро▒ுроХ்роХொро│்!
роЕродிро▓் родுрой்рокроЩ்роХро│் роЪிро▒ு родூроЪு
роЕродை роЪроХிроХ்роХроХ் роХро▒்ро▒ுроХ்роХொро│்

ро╡ாро┤்роХ்роХைропை ро╡ாро┤்ро╡родொро░ு рокாроЯроо் - роЕродை
ро╡ாро┤ுроо் роХாро▓роо் роороЯ்роЯுроо் ро╡ро┤ுро╡ாрооро▓் роХро▒்ро▒ுроХ்роХொро│்

ро╡ாро┤்роХ்роХை роТро░ு рокாро▒்роХроЯро▓் -роЕродрой்
ро╡ிроЯрод்родை роиீ роЪроХிрод்родாро▓்
роЕрооுродрооுроо் роЙройродுроЯைрооை
роЗро╡்ро╡ாро▒ு ро╡ாро┤்рои்родு ро╡ிроЯ்роЯு
роОрой்рой родுрой்рокроо் роОройроХ்роХூро▒ு
родுроЯைрок்рокродро▒்роХு роиாрой் роЙрог்роЯு - родுроЯைроХ்роХрок்
рокроЯுро╡родро▒்роХு роПродுрог்роЯு?
- роОрой்ро▒ாро░் роХроЯро╡ுро│்

AS LONG AS YOU LIVE KEEP LEARNING HOW TO LIVE

My Early Attempts In Poem Writing

Like many of my friends and acquaintances, about a decade ago I used to write poems (or at least in my view) both in English and Tamil. I used to enjoy writing them and usually they reflect a theme that suddenly comes to mind causing an urge to write a poem on that theme.

I would be posting them in my blog starting from this one:

рооிрой் ро╡ெроЯ்роЯு
роЗропрои்родிро░ рооропрооாрой ро╡ாро┤்роХ்роХை
роЗропрои்родிро░роЩ்роХро│ாрой рооройிродро░்роХро│்
роЕрой்рокுроХ்роХு роиேро░рооро▒்ро▒ - роЖро▒ு
роЕро▒ிро╡ுроХ்роХு ро╡ேро▓ைропро▒்ро▒
роЕро╡ро▓рооாрой роУроЯ்роЯроо் - роЗродிро▓்
роЕро▒ிропாрооро▓் ро╡ீро┤்рои்родுро╡ிроЯ்роЯ роиாроо்
ро╡ெро│ிро╡ро░ роОрой்рой ро╡ро┤ி
ропோроЪிроХ்роХ роиேро░рооிро▓்ро▓ை.

роЕрой்ро▒ு роЗро░ро╡ு
роЕро▓ுрод்родு роЪро▓ிрод்родு ро╡ீроЯ்роЯை
роЕроЯைрои்род роЕро░ை роорогிропிро▓்
роЕро┤ைропா ро╡ிро░ுрои்родாро│ிропாроп் ро╡рои்родு
роЕроЯைрои்родродு рооிрой் ро╡ெроЯ்роЯு.

роЕро▓ுрод்род рооройроо் роЕро▓ро▒ிропродு - роЙро│்ро│ே
роЕро▒ைрои்родродு роЕро░роЪாроЩ்роХрод்родை - роЪрокிрод்родродு
рооிрой் ро╡ாро░ிропрод்родை - роироХро░்рои்родродு роиேро░роо்
роЕрооைродி роЕроЯைрои்родродு рооройроо்
рокாро░்ро╡ை рооாро▒ிропродு:

роОро░ிропுроо் рооெро┤ுроХு ро╡ро░்род்родி
роЕродை роЪுро▒்ро▒ி ро╡ро░ுроо் ро╡ிроЯ்роЯிро▓்
роЪுро▒்ро▒ி роЕрооро░்рои்родிро░ுроХ்роХுроо் роХுроЯுроо்рокрод்родாро░்
роЪிро▒ு роиிро▒ுрод்родроо் .... роЗропрои்родிро░ роЪுро┤ро▒்роЪிропிро▓்
роЪிро▒ு роУроп்ро╡ு ... роЗропрои்родிро░ рооройிродройுроХ்роХு
роЪிрои்родройைропிро▓் родூроЩ்роХுроо் роЪிро▒ு рооройிродрой் ро╡ிро┤ிрод்родாрой்
родொро▓ைроХ்роХாроЯ்роЪிрод் родொро▓்ро▓ை роЗро▓்ро▓ா
роороЯை родிро▒рои்род рокேроЪ்роЪு - родிройрооுроо்
роЕро╡роЪро░рооாроп் роЙрогро╡ை роЕро░ைрод்род рооройிродройுроХ்роХு
роЕро╡роЪро░рооро▒்ро▒ роЙрогро╡ு
роЕроЪை рокோроЯ рокро┤роЩ்роХродை
роЗропро▒்роХைропிрой் роЪிро▒ு родீрог்роЯро▓ைропுроо்
роЗро░роХ்роХрооிрой்ро▒ிрок் рокро▒ிрод்родு ро╡ிроЯ்роЯ
роЗропрои்родிро░роЩ்роХро│ை ро╡ிроЯ்роЯு рооொроЯ்роЯை
рооாроЯிропிро▓் роиிрод்родிро░ை
роОрог்рогро▒்ро▒ ро╡ிрой் рооீрой்
роироЯு роиாропроХрооாроп் роиிро▓ро╡ு
роЪிро▓்ро▓ெрой்ро▒ родெрой்ро▒ро▓்
роУроЯுроо் рооேроХроЩ்роХро│்
роУро▓ைроХро│ிрой் роУроЪை
родூро░род்родு роЗроЯி рооுро┤роХ்роХроо்
роЗро░роЪிрод்род рокроЯி роЙро▒роХ்роХроо்.

роЗродு рокோро▓ рооேро▓ுроо் родேро╡ை
роЗрой்ройுроо் роЪிро▓ рооிрой் ро╡ெроЯ்роЯு - рооройிрод
роЗропрои்родிро░род்родை рооройிродройாроХ்роХ.

Thursday, May 27, 2010

OJT vs. Traditional Training

1.1 OJT

Definition for this purpose:

Make a just-out-of-college or almost-so new employee to work on a problem in an ongoing project and let him come through it.

Action:

The employee should be handed a problem that has enough complexity. The employee has to setup his or her environment based on the choices made for the project. The employee could solve the problem in parallel with the team. This will prevent him from being a bottleneck, but at the same time allows enough room and an actual problem to think.

Additionally he can also be made to troubleshoot some issues. These issues could be current issues or issues that have been solved but have educational value.

The employee can be presented with a list of training courses, which he can attend to accomplish the task and should be encouraged to ask for one if he is stuck.

Result:

Employee learns to solve some of the problems that may crop up, which will help in production projects. The training becomes a pull model rather than a push model. This results in better take away from training. Since the training correlates with the knowledge required to solve the problem at hand, the information gets registered better.

But, it may also turn out that the employees don’t ask for training as most of the problem might have been solved by one-off discussions.

1.2 Traditional Training

The usual training models involve pushing the information to the employee. The information contains mainly of overview of technologies, which could be easily obtained from the Net and information on standards and conventions. Most of these are not registered in the minds of the employees, as they could not match this with a real need.

1.3 Hybrid Model

A better approach will be a hybrid of the above two. Let the employee go through OJT for a month or so until enough curiosity is awakened and then put him through the training. The training should involve general, but critical information on fundamentals (e.g. fundamentals of webapps – Web server, app server, ports, request, response etc. along with show and tell with a request analyzer), specific technologies (with emphasis on practical application), unit testing. Ideally, an employee could be trained in multiple technologies and then he may align into one or many of them.

1.4 Things that have not worked

Some approaches have not worked very well in an OJT:

  • Working on an internal project

Typically, this internal project will consist only of trainees/new employees. The whole team has an air that it is an unimportant one. Most of the times the project is not utilized.

  • Involving in a live project, but without any real problem to solve i.e. left to handle routine activities
  • Giving a problem from a real project but not attaching any importance to the results or worse not expecting any result at all

Better approach will be:

  • If it is a critical internal project, create a real team for it with proper team lead and some senior developers. If not, scrap the project. If it is not important enough it is not worth developing.
  • Utilizing an employee effectively only when forced does not add any value to the team. Prepare the employee for tomorrow’s requirement. Automate routine activities and share/cycle non-automated ones amongst the team.
  • Push for the results. Use parts of the results where it could be. Expect something that could be used. Give the employee a sandbox branch in the source control for the project and let him commit his changes there.

Tuesday, March 9, 2010

Using JTestcase for unit testing - Part I

Test Driven Development (TDD) has become a very critical element in today's development with systems being more complex and time-lines and budget as tight as if not more tighter than ever. This has caused more and more unit testing frameworks and support libraries to be released. JTestcase is one such library that helps in separating test data from test cases.

While almost everyone appreciates the benefit of unit testing, when it comes to actually developing the test cases, there are various deterring factors that quickly make us lose interest in writing unit tests. One those factors is the test data. While test data for simple computations may be very easy to build, things become tough when we are dealing with domain objects that are huge and consist of complex fields within them. The mere size of them and the code that gets interspersed into the unit test code to create them adds a lot of clutter to the unit test code, making the code tedious to follow and maintain.

JTestcase helps us to separate the data from the unit test code into XML. It helps create simple domain objects easily and uses a part of JICE framework for building complex object trees. JTestcase has facilities to represent assertions in addition to test input and output data. JTestcase XML structure is as follows:

Class to be tested 1
......Method to be tested 1
...........Test case 1:
......................Param 1
......................Param 2
......................Assertion 1
......................Assertion 2
............Test Case 2
.
.
......Method to be tested 2
.
.
.

While JTestcase has support for this structure, I have found that another way of organizing test data using JTestcase seemed to work well and seemed to be in line with the expectations of various teams that I have worked with. In the subsequent parts I intend to blog the conventions that we followed when depicting data using JTestcase (along with examples),which worked very well for us.

In the meanwhile, following are the links to this framework and JICE:

JTestCase
JICE Engine

Sunday, February 28, 2010

First inspiration to blog comes from unexpected direction


I never thought I would find anything interesting to blog. But, today something inspired me to start blogging. But, the thing that inspired me was nothing amazing. It was a simple train travel. I have always liked travel and especially train travel. During my college days I used to travel back to my home town with friends and every time I used to look forward for the vacation and excited by the travel itself in addition to the excitement of meeting your dear ones again.

But, this travel that inspired me to blog is unique. I usually don't open my computer while I travel. I like to look out the window and enjoy the passing scenary. But today I thought of using my laptop aboard the train from Edinburgh to Peterborough. The first thing that struck me was, sitting by the window, it was like a corner office - with one difference though - The view out your window keeps changing. Especially in this route with scenic farmlands of Edinburgh and other places en route, small streams, river et-al in the time of the year of receding winter, welcoming spring.

This train is an east coast train and it has a decent free WiFi connection. I am writing this blog aboard that. Interesting. Thanks to technology and thanks to nature - the mix of which caused this inspiration.