21 Jun 2016

Shelfari

Recently, the Shelfari book cataloguing service was shut down by Amazon. Officially, the site was merged with GoodReads, another Amazon purchase, but effectively it was a shutdown. I've used Shelfari to track my reading habits and to maintain a list of 'must read books' for over 4 years, and I was a bit put out by the announcement, but not particularly surprised. The Shelfari site hasn't been upgraded in years, and was slow, unresponsive (both in terms of performance and mobile usage) and prone to outages.

I looked at alternative sites that I could migrate my data to (GoodReads, LibraryThing, Open Library), and decided that none of them was what I was after. Given that I only had 2 lists (books I've read, and books I want to read), a simple spreadsheet would do. So I migrated my data out from Shelfari using the data export functionality, and looked at the contents of the export file.

A cursory examination of the file (unusually, a .tsv file rather than the more popular .csv format) showed:
  1. The reading list was missing key data. Primarily, if a book was recorded twice (when I had re-read it), that book's details was completely missing from the list.
  2. The file format was invalid - it inconsistently quoted string fields (i.e. empty/null values didn't have quotes, while other values in the same column were quoted). This meant it was extremely difficult to import the data into a database/Excel to manipulate. 
In order to import my Shelfari data into an Excel file, I had to write a small command line application to carry out the conversion.  While it was an interesting exercise (I came across the excellent EPPlus and CsvHelper libraries for manipulating Excel and .csv files respectively), it took up time I could have used on other projects. Also, how is a non-programmer meant to deal with invalid data?  It is pretty poor for Amazon to ignore a site like Shelfari for years and then on shutting it down, to hamper users from accessing their own data due to an incompently coded and untested data export functionality. It also stands in stark contrast to the excellent work from both Google and Twitter in allowing users to export their data in a usable format.

Thankfully, I had taken screenshots of my book history and was able to recreate the missing book data. After managing to get all of my data into an Excel spreadsheet, I've now generated an updated list of the books I've read since joining Shelfari back in November 2011. You can view here:

17 Apr 2016

Social Media

This weekend, I’ve deleted my Twitter and LinkedIn accounts. I deleted my Facebook account years ago. It looks like I’m done on social media for good.

LinkedIn is a cesspit of recruiter slime and unsolicited offers to connect about jobs I wouldn’t offer to my cat, so it was no hardship to delete that account. But Twitter?

Death of Twitter

I used to love Twitter. I’m made some great friends there, been part of some fascinating conversations, and followed some really interesting people. But the fact is, Twitter has become a nasty place to be. I’ve seen too many people dog-piling onto others for not sharing their views, and people being abused for little or no reason. Too often lately, I’ve also found myself getting snarky with others when trying to argue a point in those rare discussions that still occasionally occur. I don’t want to spend my time in a place where people are mean to each other. I don’t want to be one of those being mean.

Apologies to all my friends on Twitter – I’ll miss catching up with you there! Please drop me a line. We can grab a coffee and stay in touch the old-fashioned, analogue way. I’ll still be posting to my blog, hopefully a bit more often than in the past year.

9 Feb 2016

Goals for 2016

As it now mid-February, it is now the time of year when I finally update you with my goals for this year. 

Recap of 2015

But before I set out my goals for the year ahead, how did I do with my goals for last year?  Well, I set out 4 goals:
  1. Start running again
  2. Get physically fit again
  3. To develop a non-trivial side project using JavaScript.
  4. Marry my girlfriend Mei.
So, tackling each in turn:

  1. Running – a partial success. I did build up my running, just not as much as I had hoped.  Looking at the sub-goals:
    1. As you can see from the graph of my monthly mileage below, trying to run 80 miles a month was probably a bit too ambitious.  I averaged just over 30 miles a month over 2015, and was hitting over 45 miles per month once I got going.
    2. I ran in one Parkrun, the Ecos run in Ballymena on Saturday 10th January 2015. Frankly, this was just too big a goal, and would have meant giving up every other Saturday morning. I needed to make this goal a lot more manageable.
  2. Get fit – a definite fail.
    1. My end of year score in the Five Minute Fitnes Challenge was 182, actually down on my personal best of  194.
    2. My bodyweight at the end of 2015 was 78.4 kg at around 23% body fat – very poor. I started 2015 weighing 80.7 kg.
  3. Develop a side project in JavaScript – Another fail! I did have a couple of side projects on the go, specifically one to export OneNote documents into markdown format, but I never got round to completing them or releasing them, due to a lack of time and interest. I’m not too concerned about this, as I have been heavily committed to my new role since April, and have been learning a lot. But I do think this something I need to look at again this year.
  4. Marry my girlfriend Mei – Yes!! Mei and I married in the summer at St. Patrick’s church in Coleraine. The massive dip in my monthly running mileage was caused by the August wedding (and associated stress) and our honeymoon cruise to Norway.
Getting married to my bride, Mei

So, based on a very mixed bag of results for last year’s goals, what about this year?  The main lessons I learnt from last year was to focus on a single big goal, and to be realistic about what you can achieve. Funnily enough, it is not the first time I’ve learnt the same lessons. So for this year:
  1. Continue to focus on my running
    1. Run 12 Parkruns by end of 2016 – a slightly more realistic target!
    2. To be running 60 miles per month by the end of the year
  2. Focus on my blog
    1. To blog a new article monthly, and to start focusing on generating more technical content for my blog.
    2. Migrate my blog away to a new blogging platform. Blogger was a good platform to start on back in March 2010, but it is definitely showing its age.  It is time for a blog makeover!!
    3. Make more time for blogging by giving up Twitter for the year. I enjoy Twitter and I have some good conversations there – but I also waste a lot of time, and occasionally I get dragged down into exchanging bile and snark. I would rather spend the time on something more meaningful and long term, like my blog and other side projects. I’ll occasionally post links to my own content on Twitter, but otherwise I’ll be avoiding it.
As usual, even if I don’t achieve my goals, I’ll hopefully learn or achieve something worthwhile.

4 Dec 2015

Sharing Code Between SharePoint Solutions

I'm currently working on upgrading a large set of SharePoint Web Part solutions from SharePoint 2010 to SharePoint 2013. As part of this work, I have been identifying code that is common to several of the solutions (logging to the ULS, decoding Claims Based Authenticated usernames) and moving it to a single common utility DLL. I thought it would be useful to document how I have done this, and to share some lessons I've learnt along the way.

NuGet

"NuGet is the package manager for the Microsoft development platform including .NET. " Taken from https://www.nuget.org

NuGet is the obvious choice for sharing a common assembly between multiple solutions. By simply adding this NuGet package (https://www.nuget.org/packages/CreateNewNuGetPackageFromProjectAfterEachBuild/) to the Visual Studio project I created for my common code, a .nupkg file was automatically created following each build.  I created a local (internal) package repository on a network share and added a post-build event to my project to push new .nupkg files to this location. Altogether, this took approximately an hour to add to my existing common utility project, and most of this was learning how to populate the NuGet package manifest.

I then added the local package source as a feed in Visual Studio (see https://docs.nuget.org/create/hosting-your-own-nuget-feeds for details), and installed the package in the various SharePoint solutions I was working on.  To ensure that I could track what version of the common utility DLL was installed, the assembly and resulting .nupkg file was versioned. As the upgrading of the solutions is ongoing, there will be a need to add additional common code to the utility assembly, and to ensure that all SharePoint solution are updated to the latest version.

Packaging and Deployment

My initial approach to package and deploy the common utility assembly was to add it as an additional assembly into the various SharePoint solution packages, (see https://msdn.microsoft.com/en-us/library/ee231595%28v=vs.120%29.aspx for details). This is the recommended approach from MSDN. It is also completely wrong.

The problem is that SharePoint packaging and deployment mechanism does not count the number of references that are made to shared assemblies used across multiple SharePoint solutions. This leads to an issue when a solution referencing the shared assembly is uninstalled, then the shared assembly is also uninstalled. This leads to the other solutions that reference the shared assembly being broken. This isn’t a new problem – it has been around since SharePoint 2010 (see http://lawrencecawood.com/2011/07/13/how-i-solved-the-problem-of-dlls-being-removed-during-wsp-uninstallation/).

In my specific case, the problem occurred when I deployed a SharePoint solution that included a new updated version of the common assembly. If I had deployed several solutions that referenced version 1.0.0.0 of the Common.dll, and then deployed an upgraded solution that referenced version 1.0.0.1 of the Common.dll, the version 1.0.0.0 Common.dll was uninstalled as part of the deployment and version 1.0.0.1 was installed instead. The new solution worked perfectly, but the other deployed solutions that still referenced version 1.0.0.0 were broken. This lead to a sticky moment following one deployment to Production. Once I twigged what the issue was, I simply redeployed the most recent WSP of a solution containing the now missing version of the common assembly.

Deployment Redux

It was clear that continuing to deploy the common assembly as an additional assembly in he SharePoint solution package wasn't an option. While it was an intermittent issue, only occurring when deploying an updated version of the common assembly, it was still a problem that could lead to unnecessary downtime. So, what other options for sharing common code were there?

After a bit of research, I came up with the following options:

  1. Deploy each new version of the Common.dll as a separate solution, deployed separately. The WSP for each version would include the version number in the name (i.e. Common.V1.0.0.1.dll) and would ned to have unique solution GUIDs for deployment. This would allow the referenced assembly to be removed from the package for web parts that reference it, so it would not be removed when deploying newer versions.
  2. Create a separate solution package to deploy the various versions of the common assembly, and several other 3rd party DLLs. This would isolate the deployment of the common assembly from the deployment of the various solutions that reference it. Obviously, if a solution referencing a new (not previously deployed) version of the common assembly is now deployed, the new solution containing the common assemblies must be updated to include the new version and also deployed.
  3. Remove versioning entirely. Simply use V1.0.0.0 of the common assembly. Instead of deleting methods, or changing method parameters, future changes would require overload existing methods and using the [Deprecated] and [Obsolete] attributes to indicate methods that have been superseded in the latest 'version' of the assembly.
  4. Merge the common assembly into a single assembly for each separate web part solution using ILMerge. This allows for the versioned common assembly be used, and results in a single DLL for each solution, avoiding additional assemblies and versioning in SharePoint altogether.

Clearly, using ILMerge was the best way forward. And it turned out to be very easy to implement with the existing solutions. The steps are:

  1. Install the Nuget package https://www.nuget.org/packages/MSBuild.ILMerge.Task/1.0.3-rc2 (it will also install a NuGet package for ILMERGE as a dependency).
  2. Clean and rebuild the solution in Visual Studio.
The resulting DLL takes the name of the parent solution, and when you check the assembly using ILSpy, it includes the namespace of the common utility code as well as that of the parent solution. Note, if you are building an assembly for a SharePoint solution, all the child assemblies must be signed.  The additional assemblies to be combined with the primary DLL must also have the Copy Local property set to TRUE (this is the default when using NuGet packages).

Hopefully, the above is of some use if you're looking for a solution to share code across multiple SharePoint solutions.

6 Oct 2015

The End of the Jobs Feed

Almost 5 years ago, I used Yahoo Pipes to put together a handy RSS feed aggregating jobs from various NI recruitment sites for software developers. Unfortunately, at the end of September, Yahoo Pipes shut down, and my jobs feed is no longer working. If you have been using the RSS feed, please accept my apologies. I completely missed the end of life announcement for Yahoo Pipes (I’ve had other things on my mind this summer).  At the minute, I have no plans (or time) to put together a replacement. If anyone is aware of any alternatives for the job feed, please let us know through the comments.  Thanks.

16 Apr 2015

Five Minute Fitness Test

In a previous post, I mentioned one of my goals for this year was to achieve a score of 250+ in the Five Minute Fitness Test. In this post, I’m going to describe the fitness test I’ll be using.

I came across the test in The Para Fitness Guide by Sam McGrath, the former Head of Parachute Training and Selection. If you’re interested in bodyweight training and getting in shape, I can’t recommend this book highly enough.  I’m particularly like this test as requires no equipment and can be done anywhere. And, as it depends on bodyweight only, it is good way to compare your relative muscular endurance over time.

The test is as follows:

  • Press-ups – as many reps in 60 seconds
  • Rest for 10 seconds
  • Sit-ups (feet secured) - as many reps in 60 seconds
  • Rest for 10 seconds
  • Star Jumps - as many reps in 60 seconds
  • Rest for 10 seconds
  • Squat Thrusts – as many Reps in 60 seconds
  • Rest for 10 seconds
  • Burpees – as many reps in 60 seconds

In the book, the following fitness scale is used based on your combined score for the above exercises:

Fitness Level Basic Recruit Soldier Paratrooper
Score 0-99 100-199 200-264 265+

So far, my best score for the test is 194, so I still have some work to do to break 250+. 

Fair warning, this test is a lot tougher than it sounds. I strongly recommend taking it easy the first time you try it. I generally do this test once a week.  But I recently came across another Five Minute Fitness Test, and I have started alternating between the two for variety.

14 Apr 2015

The Software Developer’s Guide to Interviews

I’ve just completed a round of interviews for developer roles, and thought it would be useful to post some thoughts on the process. In particular, I wanted to document what the interview can tell you, the interviewee, about the role and the company you are applying to. There are plenty of guides telling you how to prepare for an interview. I don’t know of any that tell you how to review an interview and use that information to rate the different positions and companies you’re applying to. I suspect most people just go with their gut instinct, which is usually right, but doing a systematic review may help you realise why you prefer one job offer over another.

TL;DR Version

How a company behaves during the recruitment process is a good indicator of its internal culture and what it would be like to work there.

The Ideal Recruitment Process

From my experience of both interviewing and attending interviews for developer roles, a good recruitment process will involve:

  • Write the Job Specification - The job advertisement will be based on the job specification for the role. This should specify both the essential and desirable skills and experience that applicants should have.  If possible, this should be initially be developed by senior team members for the new role. In my experience however, the larger the company, the less influence the team will have on the job specification. If you are really unlucky, the job specification will simply be a generic description for that role in the company hierarchy, and will have no information on the work you will actually be doing.
  • Form an Interview Panel - At a minimum, this should consist of a manager (preferably the manager the new hire will report directly to) and two technical interviewers (as it is harder to bullshit two people at the same time!). I personally prefer to have a member of HR also present – this helps keep the manager honest and prevent them stretching the truth when attempting to attract candidates. This is a particular issue for benefits like remote working that may not be explicitly set out in a contract. In general, the larger the interview panel, the more seriously a company takes recruitment.  A manager may also wear a technical hat, so you may only have 3 people in the panel. The interview panel will typically be responsible for setting the interview questions and defining a criteria for scoring answers.
  • CV Screening - The interview panel review the submitted CVs to the job specification and draw up a long list for interviews. This may happen after a closing date for applications, or as applications are received.
  • Telephone Screening - This is generally a 15-20 minute call from HR to discuss the application, and confirm that the applicant meets the role requirements.
  • Technical Screening – This can be a telephone interview with a senior developer discussing the interviewee’s technical background and asking a number of set technical questions.Alternatively, this may be an online programming assessment such as Codility or an onsite technical test as part of the actual interview.  The aim of the technical screen is to confirm that the applicant does have the necessary skills and experience required for the role.
  • Interview - Obviously this should be an interview with the full interview panel, who each assess the interviewee on a number of pre-set questions for which the panel have identified key answer criteria.  Typically, this would include questions on the applicant’s CV and past experience, questions specific to the role requirements and also soft skills, and then a number of technical questions.  The technical questions should cover more than just the basic job requirements – the questions should cover a range of technical levels and start at core, fundamental concepts and build to advanced topics.  The idea is to identify exactly how technically competent the interviewee is.  These questions should stretch every applicant to some extent, and will be long form in format, to allow the interview panel to force the applicant to to deep dives on specific topics. Additionally:
    • The interview described above will typically take 2 hours to complete.
    • For a developer role, this should always include some form of live coding. This is regardless of whether a technical screen was done previously or not – I’ve came across  too many developers who can BS their way through telephone screens and interviews but who are unable to code.
    • At the end, the panel leader should tell the interviewee how and when they hear the outcome of the interview.
  • Post Interview Review - The interview panel reviews each applicant immediately following the interview, and scores them using the agreed scoring criteria.  The panel’s aggregate score for each interviewee is used to decide who gets the job.
  • Job Offer – The post is offered to the successful applicant and their references are contacted.
  • Inform all Applicants – Once the job has been accepted and the references confirmed, HR should respond to all the unsuccessful applicants. This should be within the time period specified at the end of the interview. Ideally, this shouldn’t be longer than a week, but depending on salary negotiations and references, can take longer. For an automated recruitment process, this may be an online status on the candidate’s application and/or an automated email. Preferably, it should a personal response from HR, either by email or, rarely these days, a letter. 

Based on the above outline, you can see that the recruitment process is a major investment by a company over several months, with no guarantee of a successful outcome (i.e. finding a suitably experienced applicant who will accept the position within the given salary limits).  Your interview may only last an hour or two, but by comparing your experience of a company’s recruitment process to the above, you can get a sense of how they value employees, and what it would be like to work there.

Your Interview Review

OK, so you were lucky enough to be shortlisted, and you’ve just had your interview.  Sorry, but now you going to take 10 minutes to review the interview and your experience with the company.  I typically write these review notes at the end of a document I create for each job application, detailing the job requirements, company background and any questions to ask at the interview. I then update the document with any relevant notes each time I have an interview or call with the company, so I can track exactly how the application is progressing.

The points you need to consider are:

  • How has the company communicated with you since you applied to the position?  Has it been a single person communicating to you, or several, or an automated process? How did you find it – personal or completely anonymous?  How the company treats you as an applicant will typically reflect how it will treat you as an employee.
  • Was there a telephone screening interview with HR?  This is not essential, but is best practice. If it happened, it is confirmation that the company has a defined interview process.  What questions were asked?  You obviously recorded the questions, and any useful information, to prepare for your interview.  From the questions asked, you can also get a good idea of what the panel will focus on the interview, and get a better idea of the work you will actually be doing.
  • How were you tested technically?  Were you sufficiently tested? This isn’t a minor point.  If you were not tested on your knowledge and experience, then the people you will be working with will not have been tested either.  That means you will likely be working alongside some developers who don’t have the skills or experience for the job they are doing.  You might be the person who ends up carrying them.
  • Did you have to write code as part of your interview process?  If not, this is a major failing. If the company doesn’t know if you can code or not, what is the point hiring you?
  • How large was the interview panel?  This is most visible way of assessing how important a company views recruiting developers.  I would be very wary of accepting any offer from a company with less than 3 people on the interview panel, regardless of the size of the company.   Even a one person start-up should be willing to hire HR and technical consultants to have a proper interview panel. If they don’t, they haven’t a clue and you shouldn’t waste your time with them.
  • The interview itself:
    • Were the questions asked relevant to the work you believe you will be doing? 
    • Did the questions asked match the advertised job?  If it doesn’t, it is likely that the job advertised won’t be the job you will actually be doing. This means that the team doesn’t have much influence on other departments in the company – this may reflect that the team you will be joining is low down in the company’s hierarchy and priorities.
    • The interviewer’s personality and  behaviour. Were you treated with respect?  Would you like to work with these people?  Remember, in an interview, people are on their best behaviour on both sides of the table.  If you come out of an interview thinking that one of the interviewers was a pain, then they will be most likely be a complete bastard to work with. You need to trust your gut instinct about people.
  • How was the outcome communicated to you?  Was it done within the time frame set out by the interview panel?  I’ve known companies to pompously rant on about interviewees not attending interviews. The same companies will then completely ignore all unsuccessful applicants once the post is filled – this is extremely disrespectful behaviour.  If you’ve applied for a position, you will have spent several hours updating your CV, writing a custom covering letter, as well as preparing for and attending interviews.  At the very least, you deserve an email informing you that you have been unsuccessful.

Once you have completed the review, you will have a better idea of the company you may be working with. Obviously, this is only directly useful if you are offered the post, and if you have the option to refuse the offer.  Fortunately, experienced developers typically do receive multiple offers, and having an idea of the company’s culture can help you decide which offer is the best for you.  Also, even if you aren’t successful, it informs you on whether this is a company you want to apply to again in the future.

Case Study: Kana

My recent application with Kana in Belfast was one of the worst recruitment experiences that I ever had. I thought it would be worthwhile to share some notes I made after my interviews with Kana:

  • There was a brief telephone screening interview with HR, consisting of some standard questions about my CV and past experience.
  • At the first interview, I was interviewed by the team leader and a senior developer from the team I would be joining if successful. There was no one from HR present. It was a standard interview walking through my past experience and testing my technical ability. Overall it lasted around 90 minutes and was reasonably thorough. There was no coding test or any technical screening aside from the questions asked during the interview. There were a number of questions asked around my commute (I live 50 miles away from where the company is located) and my availability to work late that suggested that this is a team under significant pressure. The actual job did sound interesting (a nice mix of technologies,with a mix of both front- and back-end development), but there were a few red flags, like the focus on being able to work late.  The team leader also had a habit of talking over the senior developer that suggested they might be difficult to work with. At the end of the interview I was told I would get feedback about the interview in 2 weeks.
  • At the second interview (just under 2 weeks later), I was interviewed by the VP for Development and the Principal Architect.  It lasted approximately 60 minutes.  They asked almost exactly the same questions as had been asked at the first interview. I was also told that the role would involve a significant amount of work with Clojure, and relatively little with .NET, despite the role being advertised as a .NET Developer role with no mention of Clojure in the job description. I found the VP to be very brisk in manner, and the Architect while friendly, came across as extremely bored. Obviously, there were a number of issues here:
    • Why were the same questions being asked again?  Did the second interview panel either not speak to the first, or do they not trust their opinion?  Either way, there is a communication issue here.
    • Again, same focus on my commute and on being able to work long hours.
    • The second panel’s interpretation of the role (more Clojure, less .NET) differed from that of the first interview panel and job advertised.  Who is right?

At the end of the second interview, I was told I would be informed within a week if I had been successful or not. Both interviews were held in January 2015. It is now over 2 months later and I haven’t heard anything from Kana, despite sending a polite email asking for some feedback a few weeks ago.

It will probably come as no surprise, but I wouldn’t recommend applying to Kana based on my experience. Winking smile

What has your experience been in interviews?  Do you have your own way of reviewing job applications?  Please share in the comments below.

Thanks to Toby Osbourn for reading a draft of this post. You should read Toby’s blog Development Thoughts where he posts great articles on Ruby and web development.