Friday, 8 October 2010

Everybody's Recommending

Is Google the only one who has possibly accumulated a lot of data on your online activities?

Think again.

Most of us use one of these -
  1. Facebook
  2. Twitter
  3. ShareThis
  4. Technorati/Digg/et al

There's a common aspect to all these networks/tools - all of them can potentially collect data about the online preferences of their users. So - do they? Some of them do.

Online preferences are links that you visit, which translates to things that you are interested in. This kind of data can be used to build up a profile of the user.

Think about it -

1.  Facebook knows what you share on, knows what you "Like" among others' shared links, and now with OpenGraph knows what you "Like" on sites that have the Facebook Like button.

2.  Twitter knows what links you share, and now with - its own shortening service - it will know what links shared by others you clicked on (read "interested in"). From a Twitter blog post -
routing links through this service will eventually contribute to the metrics behind our Promoted Tweets platform and provide an important quality signal for our Resonance algorithm—the way we determine if a Tweet is relevant and interesting to users

3. ShareThis - if you're logged into ShareThis, it knows what you shared.

Links you share and visit provide a picture, albeit incomplete, of your online preferences.
The question is, how are these tools and services planning to use this data?

If you know what someone likes, you can recommend stuff to that person. A lot of sites do this already. These recommendations are based on multiple parameters. E.g. Amazon's recommendation system - which does a great job - uses collaborative filtering. Simply put, it uses data from your past purchases, ratings and I-Own-This history and from other users whose history is similar to yours. The more history you have on Amazon, the better your recommendations get.

Building a content recommendation system seems to be an obvious step once you have a data mountain of your users' likes. And this is what these sites seem to be doing but to achieve different ends.
E.g. Facebook - See slide #29 This has not happened yet, but what's  stopping it, considering what Mark Zuckerberg said earlier this year ?

Twitter has recommendation plans -

ShareThis already has behavioural advertising in the works with its segmentation technology.

The bottom line is - some of these services are going to use it to improve the end user's experience - and will do so within the boundaries of their privacy policies. The rest - we don't know.

Sunday, 23 May 2010

Instance Initializers in Java

Take a look at this simple code

Code Snippet 1

public class Init {
    System.out.println("In the beginning was the command line");

  public Init()
    System.out.println("Created an instance");

  public static void main(String[] args)
    Init init = new Init();

What do you think the output is? It's this -
    In the beginning was the command line
    Created an instance

The 'hanging' braces at the start of the class definition are instance initializers. Most of us are more familiar with static initializers -

Code Snippet 2
  //Do stuff

Instance initializers (II) are not seen often in everyday Java code - so they might seem odd at first. They are executed every time an instance of that class is created, before the statements in the constructor are executed. (See The Java Language Specification 3 section 8.6).

One use of IIs can be to execute something whenever an instance is created, and the class has multiple constructors, without calling it in every single constructor.
Another one which has become popular is populating collections during declaration, in the style of Ruby or Python single-line initializers -

Code Snippet 3
private Set<String> names = new HashSet<String>() {

This idiom was how I encountered IIs first while reading somebody's blog.
What is actually happening here?
  1. An anonymous inner class is created.
  2. An instance initializer block is added to the anon inner class.
  3. Objects are added to the instance of that class when the names variable is initialized.

Now take this scenario:

Code Snippet4
public class WrongUsage {

  private Set<String> names;

  public void WrongUsage()
    names = new HashSet<String>();

  public void add(String name)

Based on what we have seen above, the names set is used before it's initialized. So this throws a NullPointerException.
Let's take another case - similar to the above but involving inheritance.

Code Snippet 5

public class MyHashSet extends HashSet {

  public MyHashSet()
    System.out.println("After calling super");

  public static void main(String[] args)
    Set set = new MyHashSet();

This runs, with the output being
    After calling super

In this case, add() internally uses the inner HashMap inside HashSet which is initialized in the HashSet constructor. This implies that the instance initializer is invoked before the class constructor, but after the superclass constructor (The super call is redundant here. It will be called anyway).

So the sequence is
  1. Superclass initialization (this includes superclass instance initializers and constructor)
  2. Current class's Instance initializers
  3. Current class's Constructor

This is why the code in Code Snippet 3 does not throw an NPE - because it's a case of inheritance (the anon inner class is a subclass of HashSet)

Monday, 19 April 2010

How Not to do Customer Service

Anybody doing online business knows the importance of retaining and keeping their customers happy. How you do that depends on your specific business - but the starting point is always the same - Respond!
Respond - on time, with a clear actionable, and follow up.

This post is about how not to do customer service - and I am going to take a recent bad experience with one of India's top online stores - They sell books, among a lot of other things, and I have been buying from them since 2007.

I had ordered 4 books from them last month. 3 of them were shipped on time. When there was no news of the 4th one, I checked the Pending Orders page. It was not updated and stated that the book will be shipped by x - a date 4 days in the past. "Ok", I thought, "let's contact them".

I sent off a mail to their customer service ID - which I had been using earlier. An autoreply came back saying that they do not respond to queries anymore from that ID, and I have to fill out a form on their site. That would raise a support ticket.

Which I did. And the form's response promised that I would get a response within 24 hours.
Which did not happen. And their phone number is hidden in a small Contact Us link - I did not find it.
So I raised another ticket after waiting for a day.

Nothing happened.

At this point I had no visible working way of contacting them (apart from the phone number which I could not find. I attribute this to the fact that the most prominent "Help" link on their site is "Customer Support" - which points to the form mentioned above. That is what most people would click on).

So I went and posted my case on - a site where consumers can go and post their grievances. Apparently that worked - for within 4 hours I got a call from Indiaplaza about the non-availability of the book. There was no apology, though. They promised to deliver it after 7 days. Now, this was extremely surprising. It indicated that their support team checks online complaint sites for issues with Indiaplaza, but do not check their own support system!

Anyways, nothing happened after 7 days - so I went through the same ticketing system again. This time there was a delayed response (thank goodness!) stating that the book was not available. "Fine", I said, "Just refund my money". They agreed to do it within 5 days.

Nothing happened (Do you see a pattern here?) . So I raised another ticket...and so on.

Four things they could have done better

  1. The deployment of a well thought out customer support system, which is convenient to use and not just built out of considerations like it's easy to use for their support group or helps in cost cutting.
  2. Responding to my query on their ticketing system within the promised time.
  3. After not doing (2), followed by the incidents mentioned above, they could have taken extra care about this case. Once you piss off a customer, you have to do extra work to get him where he was before, and still more work to make him happy.
  4. Build a better online buying system where the status of the order is updated automatically.

The feeling that I have as a customer that I am being ignored, and especially after I have been billed, with prior experience not helping me to restore trust, is a damning indicator of what Indiaplaza lacks. They have just lost an old customer, and with the power of word of mouth these days, a lot of potential future customers as well.

Update: After raising another ticket, I finally got my refund. But I am not going back there :)

Monday, 1 March 2010

Dreaming in Code

I finished reading Dreaming in Code last week. It's Scott Rosenberg's account of a software development team's effort to build the ultimate Personal Information Manager (PIM). Led and funded by Mitch Kapor of Lotus 1-2-3 fame, the team goes through endless cycles of redesign, people issues and other upheavals.

Rosenberg follows the team very closely, participating in their meetings, interviewing them and filling the narrative with his own insights.

If a developer were to read this book, s/he would recognize the events in it this as standard stuff when developing a product, and s/he would also identify with the team itself, with the occasional shaking of the head :)

The software they set out to develop was based on Kapor's vision of a game-changing PIM. They called it Chandler, after one of Kapor's loved crossbred dogs.

This was the pre-Web 2.0 era, where most things, including product releases took longer to happen. The browser had not yet become the first medium for delivering any consumer facing application. Desktop applications for collaboration still looked as if they had potential.

Chandler's ultimate aim was to be a all-in-one tool where users could access their email, personal notes, calendar events and to do lists through one interface. Kapor visualized all these different data collections as isolated information silos. Chandler would break open and combine them. It would let you view and move around all these disparate things in a unified manner. You could tag a note with labels, and then put a date on it and make it a calendar event, or send it off as an email. Grand vision? Yes. It's something I would personally prefer to have around to manage things.

Due to numerous reasons, Chandler was late in delivering its promise. Gmail came in 2004, and opened the floodgates of what was possible using new Web technologies. Firefox arrived, and forced Microsoft to relook at IE (and make it better). Chandler was yet to release its 1.0 version. The browser was fast overtaking the desktop.

We have been spoilt by the seamless interconnectivity provided by the Internet - it's always there - home or office or a mountaintop - and with it, our data. Chandler did attempt a Web interface where you could access your data (which would be synced between your desktop and a central server), but it was too late.

The Chandler project is still on with many faithful developers. I tried out the latest version after finishing the book. My impressions? It still has a long way to go, going by the number of bugs I encountered, and assuming it can convince the Web 2.0 crowd to switch to a desktop application by the sheer force of its design and the things it is supposed to do.

The most interesting chapter in the book is "Methods" - where Rosenberg does a brief and very readable survey of the evolution of development methods over the years. This chapter can be read standalone even if you don't read the whole book.

Note: The Chandler logo image linked to here is used under a Creative Commons Attribution License 3.0.