April 21, 2009

Studiu privind salariile din IT-ul românesc pe Joobs.ro

Cu vreun an înainte să termin Facultatea de Informatică din Iaşi, am început să mă gândesc la inevitabilele negocieri de salariu de după interviurile pentru slujbe - interviuri pe care, evident, urma sa le trec "vâjâind ca vijelia" :)

Ca să-mi fac o idee despre piaţă, am întrebat în stânga şi în dreapta ce salarii au amicii mei programatori. Ei bine, am primit un număr impresionant de ... 0 (zero) răspunsuri. Unii au dat din colţ în colţ, alţii au refuzat orice fel de discuţie în legătură cu subiectul. Am încercat să pun problema altfel, întrebându-i la ce sumă cred ei că ar trebui să ţintesc. Am obţinut un succes la fel de răsunător. Plutea în aer o senzaţie ciudată de secretomanie amestecată cu paranoia (unele din persoanele cu care am încercat să discut nu voiau să-mi spună nici cât plătesc chirie sau leasing pentru maşină, ca nu cumva să-mi fac o impresie despre salariul lor ... O.o). Şi, gândiţi-vă, pe atunci economia încă nu era în criză!

Joobs.ro încearcă zilele astea să realizeze un studiu care pentru mine vine prea târziu, dar pentru care le-aş fi făcut cinste cu o navetă de bere înainte să plec în Irlanda. Studiul urmăreşte să ilustreze nivelul salariilor IT din România. Puteţi participa fără să fie nevoie să vă autentificaţi, prin completarea unui chestionar cu 5 întrebări - lucru care probabil vă va lua mai puţin timp decât v-a luat citirea acestui post.

April 20, 2009

First update to the mobile device browser file!

We've released the first update to the mobile device browser file that I was talking about in a previous post. We've added support for nearly 100 more devices and for the canInitiateVoiceCall capability.

You can download the file and see the release notes here.

April 17, 2009

How do you design exception handling?

A while ago I took over an internal tool with the task of turning it into a reusable component and enhancing it with new features. Given that it had been conceived as a command-line tool to be used only by the other developers in the team, the author of the code had a very simple exception handling policy: let'em all bubble up until they splash at the console - the user will know what to do.

So I rolled my sleeves up and started writing exception handling, and I was struck at how much grief it gave me. I knew the guidelines, I knew the recommendations, I knew the practices, but when I got down to the nitty gritty, it still felt on-the-fly, I still had the feeling that I wasn't doing it right, that it wasn't robust enough.

Last week I attended a 4-day training session on Design Patterns with Alan Shalloway, main author of Design patterns explained. The ~20 hours of training were very good, but as they were drawing to an end, I realised that not once had he mentioned exception and error handling. Alan did seem intimately familiar with the literature on design patterns and object orientation however, so I thought he would be the perfect person to ask: "How can I learn about designing exception handling? Has anybody written about that?".

But when he answered that he didn't quite know, I started thinking that exception handling design is an undeserving neglected topic. And the more I thought about, the more evidence I found. Think about it, how many times did you write a design document that included a section on exception handling? How many times did you design an interface and put serious thought into defining a set of exceptions for implementors to throw in a consistent manner?

How about it, then? Have you learned or worked out any design patterns for exception handling? I mean something more cohesive than your usual set of "do this / don't do that" guidelines, something reusable at design time rather than at implementation time. I'd very much like to hear from you on this subject.

April 11, 2009

Color settings for a Visual Studio dark theme

I've finally decided to change my Visual Studio text editor color settings. I aimed for a dark-background theme with rather mild colors which I felt would decrease the amount of stress that hours of coding put on my eyes. I also wanted comments to fade into the background as much as possible because I was becoming annoyed by large (albeit necessary) XML documentation headers taking away emphasis from the actual code.

I was pretty excited the day that I started using the new settings and I ended up staying at work until 21:30, writing code just because it looked good.



I let XML be a little brighter than C# code, having orange attributes. Otherwise, the two are visually consistent.



I've made the .vssettings file available on Sky Drive for you to download and tweak to your taste. If you have ReSharper, you'll notice that I've also changed its highlighting settings to match the VS text editor. You can import the settings into Visual Studio via Tools -> Import and Export Settings.

Enjoy!

April 02, 2009

StringComparison.Ordinal when overriding Equals and GetHashCode in .NET

Suppose we have a class that contains string members* and that as far as our business logic is concerned, two instances of this class are equal if their string members are respectively equal, regardless of casing.

So, following MSDN's recommendation, we use OrdinalIgnoreCase comparison in our Equals() method, like so:
class Item
{
private string code;

[..]

public bool Equals(Item other)
{
return
String.Equals(code, other.code, StringComparison.OrdinalIgnoreCase);
}
}
Then, giving heed to another MSDN recommendation, we decide to override the GetHashCode() method. And herein lies the dilemma: how do we implement GetHashCode() so that it is consistent with Equals()? How do we make sure that for every pair of instances that our Equals() method deems equal, GetHashCode() will return the same value?

We obviously need a way to normalize our class's string members, and our friends String.ToUpper() and String.ToLower() are very eager to jump to our aid! But alas, ToUpper() and ToLower() are culture dependent (even if we're talking about the invariant culture), whereas OrdinalIgnoreCase is anything but that. Or is it?

Well, as it turns out, OrdinalIgnoreCase performs byte-based comparison as long as it operates in the ASCII spectrum, outside of which it behaves precisely the same as InvariantCultureIgnoreCase.

And so, we can whip up a sound solution for GetHashCode():

public int GetHashCode()
{
return code.ToUpperInvariant().GetHashCode();
}

* (that are never going to be displayed to a user and have no linguistic significance)