Wednesday, December 31, 2014

Future

More than six years ago I started this blog. I wanted to practice my English so that I would improve it.

Four years later I came to London and sort of abandoned it, thinking that working in an English speaking environment would be enough to practice.

But it is not. I really think blogging is a good way to improve your written expression, to clarify your thoughts. And sometimes what you tell is worthwhile for others. It is not specifically related to speaking a different language (but it also helps that).

So my New Year's resolution is to write more often. Just to practice. And hoping this could be of use for somebody.

Happy New Year.


Thursday, December 25, 2014

Happy Christmas

Happy Christmas and a wonderful 2015 to all of my readers.

Monday, December 22, 2014

I'm a geek


A few weeks ago, I bid and won a PowerEdge 2650 server for three quids (plus another 6 of renting a car and collecting it).

It´s an old piece of hardware (32 bits double Xeon, 4gb of RAM), bulky as hell (or so does my back says) and noisy as a diesel generator.

When I came home, my daughters said that couldn't be a computer as it didn't have input/output devices like a keyboard or a monitor. I didn't bother to explain a server does not need a screen or a keyboard. Whether that's correct is arguable. They are learning Computer Science at school, and I only interfere when I see a big mistake.

Anyway, bringing home the computer was only part of the project. Hey, I'm a geek, but having a server on the floor of my dining room is not where the fun lies even if my wife allows it. First, I needed to open its case, take a look at the the inside (a bit insane, yes I know).

Then, I needed to install the operating system. I thought that was going to be easy. I install different operating systems all the time. But...

... I usually install using an USB drive and the server would refuse to boot up from the USB drive.

OK. It has CD-reader but ...

... I don´t have a CD-Writer. Who writes CDs anyway?

Already thinking how/where to record a CD, I decided to investigate something called PXE. PXE tends to appear in many BIOS as install from the network. In very general terms, the BIOS is enough to look for a DHCP server that looks for sort of FTP server, that provides a typical file that allows to install an Operating System.

Unfortunately, I only had a Windows machine available (having two daughters in secondary school, Linux has been unfortunately relegated)

But there is an old post that explain how to install Ubuntu from windows. The only tweak was the needed to get some current image. You need to get the image from this URL

One small tweak while installing is something that had already happened while installing a server at work. The screen would go blank with the message "Cannot display this video mode". A quick search, and one of the first results was what I needed.

Once I installed the basic server, I only installed SSH server. The rest of the server was going to be installed using Ansible. Another topic for another time

I´m a geek.

And, my wife doesn't read my blog and she is a saint.

Saturday, October 4, 2014

Agile is about managing risk

It is not easy to explain what is agile or the need of agile practices in software development. Agile is not only about releasing early a valuable product even if it is the highest priority.

Anyway, a few days ago I found this tweet:

I showed the picture to my wife, and I tried to explain it to her. It was funny because she couldn't understand what's wrong with the first part of the picture and why the second one is the proper way to build software. She insisted that if you want to build a car, you should do the a wheel the proper way, then the other wheel, then the body and finally you deliver the car.

So why many people in the software development world are trying to deliver a skateboard, and then a bike, and then a scooter, and finally a car?

I think it is about managing risk.

It is not about following the coolest paradigm or techniques. But about identifying what usually goes wrong when developing software, and providing solutions.

Users complain that what they receive is not what they asked for, it is delivered late, and it costs too much. Software developers say users don't know what they want, and they keep changing the vision throughout the project. As a result, many software projects end as a failure

To avoid it, the typical solution is to increase the requirements analysis phase (not a straw-man, see previous link). You set in stone what the user wants and if the user changes his/her opinion (or he/she doesn't understand what appears on the requirements document), bad for him/her. Then, the software is designed, properly built, tested and deployed. And finally (or at least later in the process) you put a wrap and show it to the user. I call it a waterfall mindset.

Traditional software development

From a pure risk perspective that is a lot of uncertainty. We don't know if that is what the user wants. We don't know if we'll deliver on time. Any change could have catastrophic consequences. Your product is not ready to look until very late in the process.

Agile is almost the opposite. It's about delivering early, something that can be used right from the start, and slowly enhance it. It is about talking with the user throughout the process. It is about developing software WITH the user. Problems tend to appear early in the process, and you tackle them as they appear. Sometimes problems are the result of a growth without a blueprint, and you need to rebuild things you've already built. But that's OK, because Agile is about facing risks.

I've been part of teams with daily stand-ups, with sprints, with code reviews, but with a waterfall mindset. Agile shouldn't be a warm feeling of this is right, or cool. Agile should be a way to minimize risk. 

Saturday, July 12, 2014

Jetty

Lately I've had three different issues with Jetty. Two of them were those kind of issues that are not directly related to the problem. The third proved to be a bit more tricky.

The first one was the typical example of "correlation does not equal causation". I started getting a weird error trying to run a Scala based web application in Jetty. And I kept received the following error "Could not create symlink /tmp". I thought it could be related to some kind of permissions issue. In the end the problem was more basic: I'd exhausted all the free space and nothing could be written to disk (and jetty couldn't create a symlink).

The second one was one of those Doh! moments. My web application didn't respond to any request. But it didn't show any error in the logs. I'm quite ashamed of putting this in writing but the issue was that the web application was paused in a breakpoint while debugging.

The third one was a bit strange. The web application obviously has static files. Some of the Javascript files were served correctly, other Javascript files weren't. The files not served were always the same. I didn't detect any specific pattern. But the fact was that Chrome would receive net::ERR_EMPTY_RESPONSE, and the Jetty was logging an exception NoSuchMethodError in javax.servlet.http.HttpServletRequest.isAsyncStarted  

The typical answer relates the problem to having several versions of the servlet api. But I somehow didn't pay too much attention because [sarcasm on] everybody knows servlet-api.2.5 and javax.servlet-api-3.1.0 are not different versions of the same API [sarcasm off] (indeed they ARE different versions of the servlet API)

Sunday, June 8, 2014

Android 4.4.3: Sony Xperia U

A few months ago, I upgraded the firmware for my Sony Xperia U. It turns out that the place I used to download the firmware updates from, wasn't providing new updates, so sometime ago, I migrated to a new source of firmware updates.

I knew that Cyanogenmod was already providing Over The Air (OTA) updates. What I didn't know is that today's update would bring Android 4.4.3 when even people with a Nexus 7 has not receive Google's update yet.

Over the air. No glitches. 

That's awesome.

Scala: First impressions

A couple of months ago I started working for a different company. I'm quite happy there for many reasons. But one of them is having the opportunity to learn a new language: Scala. It's uncommon to get a programming job when you don't know the syntax of the programming language used. But if you really think about it, it's much better to hire somebody passionate about technology and that really loves to learn (and commit) than somebody that knows the language but doesn't give a d***mn.

Anyway, after a couple of months, I thought it would be good to write my experience about the language.

First. What is Scala? Scala is a programming language that allows to develop both Object Oriented Programming and Functional programming. Functional programming is a new paradigm of developing that is opposed to Imperative programming. In a nutshell, imagine SQL, the language for querying databases. When writing a query you don't write code like "Take the first row, check if satisfies the WHERE clause, if it does, append to the list of results, take the following row...". You simply specify the criteria for the results and that's it.

But that way of querying with SQL that it's inside of almost every developer's brain, involves a new way of thinking about problems for things that are not database queries. And, believe me, it takes time to learn. To the point that today, a couple of months later, and halfway a course devoted to it, I keep writing imperative instead of Functional code.

One could ask "if it is that complicated, why bother?". Multithreading is tricky, but CPUs have stopped increasing speed and they are increasing number of cores, which implies concurrency. Functional programming promises to help in that process. And in fact, one the emerging libraries in the Java field, the akka library, comes from the Scala world. The famous lambda in Java 8 is functional programming.

Regarding the specific language (not the functional paradigm), I have mixed feelings. I find it brilliant sometimes. And others I see it weird. As an example, I love the tuple concept (the ability for a function to return a couple of values at the same time without defining a class for that). But I almost scream each time I have to refer to the first element of the tuple with an _1 (as opposed to the typical _0).

I remember loving Ruby and Rails almost in any line of code. Everything felt natural and although in retrospective there were weird things, my general feeling was that code flows. With Scala I'm just starting to feel productive. With Scala love appears, but it tends to be in "this is freaking awesome" moments from time to time. [OMG, love and code. I'm really a nerd, isn't it?]

Don't get me wrong. Once you get the hang of Scala, it is much much much better than Java. It has a strong typing system like java, but with type inference that allows to skip types in some declarations. It tends to be concise (sometimes to the extreme). In its origin, Scala allowed to generate code both for the JVM and .NET runtime environments. I suspect that's no longer the case and nobody develops in Scala using the .NET.

One thing I find mind blowing (for bad and for good) is implicits. Implicits allow a type to be considered as a different one, upgrading the type to a different one. That is very powerful because the implicit mechanism relies in transforming functions (instead of inheritance or casting). Believe me when I say it is brilliant. But sometimes it leaves you scratching your head thinking why your code does not work until you remember to import the proper implicit conversion function.

The editor would need a post on its own. There is an Eclipse version for Scala. But until last Monday, I wasn't able to do automatic indentation without risking to mangle my code. Refactoring is for brave. And I'm living in nightly updates for Scala-IDE. I've been told that IntelliJ is much better, but I'm trying to avoid it.

Finally, learning a new language is not only the language itself, but a whole array of technologies around. OK. You learn Scala, and then you need to learn a web framework. Play would be the equivalent to the latest versions of Spring MVC or even Rails. But I'm in a love-hate relationship with lift (which I find absolutely different to anything else except for Meteor).  And you also need an ORM. The typical one would be hibernate in the Java world or ActiveRecord for ruby. Slick is not the more used, but it is really promising.

And that's it.

I'm REALLY happy of being able to learn Scala. And I think it has transformed my programming habits for years to come (and it will do more if I leave behind the beginner level).

To the point that I read val instead of let.

I'm not entirely sure I would use Scala for all kind of projects. But certainly I would do for backend mission-critical code.

Thursday, May 29, 2014

Maximizing Macbook Pro's battery

I have an old Dell Vostro 1720 and an Acer Aspire One AO110. Both are usable (and used), but have no battery.

So when I got my shiny brand new Mac, I decided I had to look after the battery.

And I read everything I could find about how to take care Macbook's battery.

Apparently, old models used to need a periodic full discharge followed by a full recharge.

Apparently, that is no longer the case.

I've tried to follow the advice in Apple's page, and I tend to leave it unplugged every day once or more times while working with it.

And I've noticed that from a Full Charge Capacity of around 8500 mAh, it has been improving to around 9000 mAh

It is too soon to know how it will last in the future, but it is a good sympton.

You can check full charge capacity at "System Information". Go to "About this Mac", then click on "More info...",  then on "System Report" and finally select "Power".




Friday, May 9, 2014

Good examples

I was made redundant at the end of March. It was a very stressful process but it ended up very well, as I've been in my new job for almost a month and I'm very happy.

During process, I had to work with lots of recruiters. Both from inside and outside my former company. One thing many people in the recruiting industry fail to understand is that every interaction counts. For better or for worse.

There were also people who just do their jobs. And that's OK.

There were also bad apples. I think it would be useless to point them.

But there were some very few absolutely brilliant. I remember one specific case. When each and every interaction is memorable, you know who you are going to recommend if asked.

Thursday, April 24, 2014

PDOException

Small and uninteresting post. But I've been dealing with an issue for hours and maybe somebody can benefit from this in the future.

While trying to index using Sphinx, I was getting the following error

[PDOException]                                  
  SQLSTATE[HY000] [2002] No such file or directory


The issue was not related to Sphinx, but to a related connection between PHP/Symphony2 and MySQL. Unfortunately the PHP web application and MySQL were working together and that made the issue more difficult to track.

Most of the replies around the Internet involve file sockets and the like. 

The real solution is not to connect to "localhost", but to 127.0.0.1

Yeah. I know localhost and 127.0.0.1 should be the same. Apparently it is a Mac weirdness. Beats me!!!

Saturday, March 15, 2014

Acquisitions

Today I wanted to talk about two acquisitions.

  • On one side, Facebook and Whatsapp. $19 billion. There are many different opinions. Craziness. Logic. IMO the money paid is crazy, but the deal has a lot of logic for Facebook. Because for many people around me (including teens), Whatsapp is THE social network. They(we?) share things like images and videos, status. We use it almost everyday. Food for thought: when was the last time you got to know anything reading it on Facebook? 
  • On the other side, Simple and BBVA. Simple wants to be the new bank. And it has been bought by a well known international Spanish bank. $117 million. I worked for one of the banks that end up being BBVA in 1999. Very interesting project by the way (Data Warehouse). At that time, BBVA launched a pure online bank called Uno-e. It was supposed to be the way to go. Very appealing technology. Santander, another international Spanish bank bought something called Patagon. 15 years later Patagon does not exist (it is called Openbank). But both Openbank and Uno-e languish in the Spanish local market. I would be surprised if Simple does not follow a similar path.

I know there will be lots of different perspectives. But don't think about the amount. Think about the whole picture.


Thursday, March 13, 2014

Optimizing

A few days ago I went to a meeting and we were discussing (among lots of different topics) various optimizing mechanisms for a web application.

After the meeting had ended, I came to the conclusion that, implicit in all the conversation, I was not fully aware of the most obvious step previous to any optimization:

Measure

You cannot optimize if you don't know what do you need to optimize. Is it a database problem? A web problem?

The guy interviewing had tried to push me further.  What to measure? Memory, CPU and request time I vaguely remember replying. What tools to use? At that point I probably screwed up the meeting, but that worth a post on its own.

I was thinking along these terms while preparing for a different interview. And I suddenly realized that "what to measure" is also important and the answer I provided can be valid but is not the only one. Yes, I knew it from courses. But now I've learnt it.

Good thing about selection processes is that you learn a lot from the processes themselves.

Wednesday, March 12, 2014

Tipping point

I'm happy. 

I was developing a feature that allows to export from my showcase project Whendoigo to TripIt

I was using a gem from TripIt. A gem is kind of a library for Ruby (sort of jar for Java). The gem simply encapsulated the API from TripIt. But it was failing and apparently everything on my project was correct. So this time it didn't took me too long to start debugging the actual gem's code.

The exception had traces with ActiveRecord references. ActiveRecord is an ORM, (think Hibernate or iBatis for Java). It's part of Rails. And the gem shouldn't have any dealing with ActiveRecord

The code that was failing was a bit difficult to understand. It uses one of the more powerful features in Ruby called meta-programming, but not with the more typical ways. Trying to put into words, it was creating a class with a dynamic name on the fly, and then instantiating an object of that class. 

What happens when the name it is trying to use is already being used in a different part of the application? To avoid that issue, the gem was creating the names with a namespace. 

And that should have been all.

But it wasn't. Lots of debugging and some restructuring later I found the problem. 

The names were being cached and when asking for the names it was asking for the names with the namespace... or without it. 

Two lines of code. A pull request. It took me a while. 

Not many people would appreciate the reason. 

But I'm really happy.


Thursday, February 27, 2014

I was sure it was my fault...

... but it wasn't.

In the last week or so, I've been hitting against a wall because of two different bugs. I was sure that both bugs were my fault. It took me ages (of a scarce spare time) trying different things, searching for similar problems, until in both cases I finally came to an issue in different tools. As I haven't found too much information, I've decided to put it in writing.


  • First, trying to use Boostrap (a framework for presentation: sort of a CSS template), and using the grid system (a way to organize things in columns, rows and cells), I wasn't able to get things in the same row and they appeared stacked. The issue turned out to be I was using an old Bootstrap version (3.0.0rc1). Upgrading to a newer version (3.1.1) solved the problem
  • Second, again using Bootstrap and its icons (glyphs as they call it), I couldn't help but notice that the icons didn't load properly until the mouse was over the icon (hover). The usual answer on the internet for not loading icons in Bootstrap is "check the class" (it doesn't help that class name for glyphs have changed from Bootstrap 2 to Bootstrap 3). The second most typical answer is related to Firefox (I was using Chrome). Finally I managed to remember that the icons in Bootstrap 3 are fonts. Which led me to know there is a nasty bug hitting Chrome stable with the following title "External Font not rendering until forced repaint". Ouch.


By the way. "It must be my fault" is much better than "it's not my fault". But biases are not good, whether one way or another.

Friday, January 31, 2014

Community managers: The day after

Yesterday I followed on Twitter a case where the community manager for a -well known and with very good reputation- Spanish moving company literally screwed up their reputation.

He/she threatened to sue a customer that was expressing a complaint on Twitter, because the client had used the hash tag "vergonzoso" (shameful). IMO, the customer was not insulting and she was not threatening. Just complaining.

Initially I thought about yet another tactic to be viral. But the reputation of Gil-Stauffer in Spain is completely different. It's the kind of company you would like for a good, incident-free, priced, removal. Sort of a Zappos for Spanish removals. Or that was my impression, at least. After a bit of researching, it seems the incident is not something new. But this time the backslash is going to be very tough.

So you're a CEO of a big company and you discover that the technology everybody told you it would help interacting with your clients, has literally destroy your reputation. I'm sure the CEO did know about the tactics, but now he/she knows this time is different. What to do?

Some possibilities comes to mind:

  • Ignore as if nothing had happened. It has worked in the past. And it's tempting. But it's flawed, because social networks are about communicating. And because this time is different. Next tweet on that account is going to be replied by hundreds of people.
  • Hide it (deleting the tweets). No worth even considering. Everybody has now a capture of the tweets.
  • Rebuild trust.

In my opinion, the only real option in a social networked environment is to rebuild trust.

  • You need to act quickly. Rebuilding trust takes time. But you must start as soon as possible. I imagine the management did know yesterday about the major screw up. But today there is no answer. Which means they don't know how to act. And they're obviously considering the options. But if you don't act quickly, you'll be forced to act later on, but losing the benefits.
  • Apologize. Clearly. Not only for the specific series of comments but also for not understanding the whole social-network issue. Explain you have learnt -where "you" means the CEO- that social networks are a different thing you didn't understand. And that you personally are going to learn.
  • Start listening. There is a customer that has not get a good experience. Change it. Solve her problem. I remember having a bad experience with IKEA that was completely reversed to a great experience thanks to their Customer Relationship department.

Social networks are about interacting with your customers and getting feedback. It's about listening.

It is not a new channel to fill with Press Releases or (worse) to threaten clients.

Update: They finally manage to apologize (and also on the general issue). Late.

Tuesday, January 21, 2014

Multithreading: Warning lights

A few days ago I went to an interview which included a pair programming session. The session was a great experience, but the result wasn't quite as good as it should have been, because of some difficulties understanding on what was being asked. It didn't help it was my first experience working with a Mac.

At one point we agreed on creating a new constructor so that we could pass a service in the constructor instead of getting directly in the method under test.

So I had something like (fictitious code)

  class GreatObject {
    public void calculateAndAddAmount(int length,
          boolean cheapService) {
      int cost;
      if (cheapService) {
        cost=length*3;
      } else {
        cost=length*8;
      }
   
      Service supaService= MegaFactory.getService();
   
      supaService.addCost(cost);
    }
  }

and we had agreed on doing something like

  class GreatObject {
    private Service supaService;
    public GreatObject () {
      this.supaService= MegaFactory.getService();
    }
    public GreatObject (Service supaService) {
      this.supaService=supaService;
    }
   
    public void calculateAndAddAmount(int length,
          boolean cheapService) {
      int cost;
      if (cheapService) {
        cost=length*3;
      } else {
        cost=length*8;
      }
   
      supaService.addCost(cost);
    }
  }

When I was going to do it, something in the back of my mind started to blink. It was a bit subtle and it took me a while to be able to express it. So as an exercise for the future, I'm going to try and express it in writing.

The problem with the change is that we have transformed a local variable into an instance variable. Local variables are local to the thread. Instance variables are shared between threads. So until now we had a thread safe class, but now the class is not thread safe. As an example: What if each instance of the service can only be invoked once and we have two threads running?

I was asked to tell what to do to be protected. I replied I didn't know. The typical answer involves the reserved word synchronized. But as I've told in the past, that is not usually a good answer and almost never the best answer.

Sunday, January 12, 2014

It's great when your idea is a good one. But...

Since I came to London, more than a year ago, I've been travelling a lot back to Spain. I used to schedule trips in advance, and once I discovered I had two different reserves for the same trip (fortunately I was able to change one of them). Soon I realized I needed some tool to manage the trips.

I did a quick search and I couldn't find anything.

Then my wife and daughters finally came here. And I had even more trips to schedule. We needed to plan well in advance, because trips where more than three times more expensive (when travelling with children I cannot afford to wait queues hoping to get a good seat nor fly to a distant airport to save some pounds). Also, people in Spain started to come and visit us, and we also needed to plan that.

So I had my own itch to scratch, which is the better way to commit to something. 

But my own requirements could be expanded to accommodate similar requirements from businesses. And businesses pay. I had a business plan. Not for the next social network, but for a small web application. I also wanted to practice Rails. 

So I started to build it. In my own free time. I built a quick and dirty prototype. And I started to build something more serious

Today I discovered that there is indeed something similar. A quick sign up told me most of the things I envisioned (including emailing confirmations to ease the pain in managing trip status) are already there. 

And it is made by one of the big grands in expense and travel management.

Three lessons learned:
  • Do a proper research.
  • Commit. Commit. Commit.
  • It's great when your idea is a good one. You're no longer a freak who prefers the cloud to a notebook.
And yes. I have other ideas. But ideas are just a multiplier. The question is if I'll be able to commit.