Pages

Showing posts with label howto. Show all posts
Showing posts with label howto. Show all posts

Software Programming Interviews Part 4 - Take-Home Tests

Take-home tests are great! All I have to say on this topic is, this is your chance to prove your mettle on your terms.

Nobody watching over your shoulder scrutinizing each thought and line of pseudo-code. No interactive tap-dance like the kind in face to face onsites. You get to iterate, test, pretty-fy, document, and package the hell out of it. Give it all you have.

Why an entire blog post for this? Because it is that valuable in the candidate's interview process and will only grow in favor with hiring teams.

Software Programming Interviews Part 3 - Getting Noticed

Take a look at your resume. A significant part of it lists software projects with technical descriptions. These projects help establish your areas of familiarity or expertise. Do they stand you apart from the crowd? Hint: its a rhetorical question.

All that falling-over-each-other-to-grab-the-coolest-project-at-work - when will it come handy you ask? One word: over-rated!

How about coursera/udemy or other online courses and certifications? Fantastic for self-learning but don't expect to be demonstrating your individual value based on these diplomas.

How about your Linked In profile where hyperbole is the norm? Loaded question, you might say but you get my point.

Does GPA matter? The truth is that its value ages out faster than you think once you graduate.

Let's step back a little bit and absorb the big picture:

The best hiring scenario is where the team has a clear understanding of your value before the face to face. Let this sink in a bit. The onsite face to face must only validate their previous assessment of your value. Dotting the i's and crossing the t's as its called.

The scenario I described poses least frustrations for both the candidate and the hiring team. Fewer surprises and less pressure during the face to face paves the way for starting career relationships rather than managing sweaty palms, beaded foreheads and out-of-the-natural behavior patterns.

So to re-state our problem statement:
How do you stand apart and establish value before the onsite?

Seems impossible, does it? Since I'm feeling generous with hints, here's one more: This bit takes a year or two of work in the least. The good news is that it is never too late to start.

We live in what is called the 'reputation economy'. An entity - in this case you - is associated with a score or 'reputation' that is accrued by being valuable to a crowd. Stack Overflow is the classic example which quantifies how much value you are adding to the community. Reputation could also be qualitative. Speaking at tech conferences, chairing standards working committees, competing in international coding competitions or local hackathons, contributing to open source or maintaining your own, blogging about pet projects, all earn respect. Being published and/or having patents to your name also has a similar effect.

Jump right in - this is your best bet. Be a presence in the public domain as a value-contributor. There are tons of paths to pick from. If you don't know initially where you fit, try many things until you find your thing. Identify your affinity, carve time out of your personal schedule and throw yourself headlong into it. And then make it count.

One final word on your resume since we are on the topic: in the current age where all your career information is published on Linked In, what is the role of the resume? Besides, does it need to be 5, 3 or even 2 pages long? Hint: rhetorical question!!!

Software Programming Interviews Part 2 - Whatever is 'Culture Fit'!

Part 1 of this series is a perfect segue for this hot button topic - Culture Fit. What is it? Is it a hoax and/or an HR tool to explain away anomalies in hiring patterns? Must you care? How does one prepare for this?

Newsflash - Culture Fit is real whether you like it or not. Yes, it is a much-abused term, and often an easy crutch to explain away hiring biases. However, a 'team' is not an objective, automated entity. A team is only people who work together. When a new hire joins an already successful team, it is that same infamous 'Culture Fit' done right that keeps the team on the success trajectory. Or in a better outcome, even accelerates it.

The way I see it is like so: every team is a 'virtual person'. Every team has one single collective pulse, IQ, ethics, voice and image. By 'collective' I don't mean 'homogenous', rather a common fabric that holds together diversity successfully. It is the Fit with this collective presence that represents to me Culture Fit. The biases play out when consciously or (more likely) sub-consciously a team favors more of the same, or is swayed by stereotypes. If you do sense it and would like to make a change, you are probably most effective in influencing it after you join that team.

Corporate culture has an unstated baseline with collaboration, verbal/written communication, and body language. These lend very easily to conscious preparation which is not merely applicable to interviews but also to day to day work life.

There may be other aspects that you can train yourself for as part of continuous development. How well do you listen? How effective is your questioning and critical thinking? When presented with an alternate proposal or idea, how open are you to evaluating it against your own?

Then there are aspects may be closer to your core personality and harder (but not impossible) to change: What do you do when you hit a wall or draw a blank with a problem? If you want to change this behavior, you have options and now you have to make a choice. That choice may or may not align with the team you are interviewing for.

Do you ask for help and if so, at what point in the problem solving? This again is tied to core personality which reveals tenacity, self-driven-ness and initiative.

I don't intend to present here an exhaustive checklist of behavior patterns and scenarios. And in fact, many of these don't have a right or wrong answer.

Know that Culture Fit is not often consciously tested for in technical interviews. However, a mis-alignment (whether governed by sub-conscious bias or not) quickly gets noticed as a red flag.

Do your research on the company culture and if possible, the team's. Analyze the interviewers carefully to better understand the team culture. Ask questions if needed. If you do want to adapt yourself to the team, understand that you are doing so not just for the interview but for that job role. Finally, be authentic and do not lie!

Software Programming Interviews Part 1 - Technical Questions

I am in a unique relationship with interviewing currently. To illustrate my point, here is a breakdown of the most recent 5 months in my career:

month 1: Update resume and relevant career sites; search for jobs and apply
months 2 and 3: Interview with fervor
month 4: Negotiate multiple offers, accept one and resign from then current employment
month 5: Join my new team and interview candidates for rest of the reqs at the rate of 3 interviews a week

It is the 5th month of this journey that stands me apart. In almost a continuum, I moved from one side of the interview desk to the other and the perspectives this has endowed me with are priceless.

I am attempting to capture my thoughts and observations in a multi-part blog post starting with this one. I don't plan on posting interview problems to solve and which companies ask what sorts of questions. There are plenty other great places where that information is available.

These are my personal views and do not reflect my employer's. Point to note also is that some aspects are topical or even locational and much is subject to change with various factors that affect hiring and the economy.

I'll start with my pet peeve about technical interviews:
Why *are* the questions book-ish and academic? Why aren't they more relevant to what is applied? 

For example: Honest to goodness, I haven't had the need to use AVL trees in my entire career of 15 years of C programming. In the meanwhile, I have extensively used the Patricia Trie, the radix tree, the hash map and doubly linked list. Why then should I go back to the books to refresh on re-balancing of trees and convoluted algorithms for singly linked lists?

The most obvious reasoning is that the favored set of problems stems from foundational CS. So when you are able to convince the hiring team that you have nailed the foundations, there is greater confidence.

Then there are practicalities - the problems must be solvable in a short period of time and general enough to intersect a wide array of domains and expertise. They must be simple enough to help the review process, but complex enough to judge creativity. Makes sense?

I wasn't convinced entirely with these answers. While I plowed along with my interviews in months 2 and 3, a signal started to emerge from the noise. What I discovered may surprise you. Technical interviews - especially the face to face ones - have very little to do with 'coding kung-fu' and a lot to do with personality testing. Just as a body language expert looks for clues in behavior - those 'honest moments'  - that reveal uncertainty, truth or lie, the hiring team uses the opportunity to pick up on whether each is able to see a working partnership in the candidate.

The first take away therefore is, an interview is anything but an exam. The hiring process is more analogous to match-making; complex, non-linear and very very personal. All that (often annoying) groundwork with practice problems and textbook refreshers is necessary to start playing but whether you get an offer or not relies a lot more than you think on the person that you are.

And here's another thing: the responsibility of finding that perfect match lies equally on either side of the hiring.

This has huge implications and dictates how you prepare yourself, present yourself and process a hit or a miss. Introspect, get in the shoes of the hiring side, and pay close attention to the 'soft' or 'behavior' aspects. Preparing for behavior questions is a slam dunk one would think but often ignored by the techies. That's low hanging fruit. What will really set you apart is your preparation to present a certain conscious behavior pattern while solving technical problems. Did I mention: introspect!!!

Mystery of the Shared Library - Solved!

The first technical problem to solve for the ONF submission was figuring out the naming and compiling of a shared library. The second was to link it with the application (SDN controller).

The secret sauce is the Makefile. Below are the instructions. The complete code is available here. Go ahead and test it out.

1. The naming: These names have very specific use while installing the library. Take notice.

major version: Anytime the API changes, the major version needs to increment. Numbering starts at zero.

minor version: Any upgrades to the library that does not have API changes increments the minor version. Numbering starts at zero.

name:  Pick the name you want to be used in the -l switch when linking this with the application.
In the github example, this is smalle.

library name: lib<name>.so
In the github example, this is libsmalle.so.

soname: lib<name>.so.<major ver>
In the github example, this is libsmalle.so.0

real name: lib<name>.so.<major ver>.<minor ver>
In the github example, this is libsmalle.so.0.0.

The library is compiled to create a file with the real name. The soname and library names are symlinks created at the time of installing the library.

2. GCC flags:
Sources are compiled to object files using CFLAGS with gcc. The must-have CFLAGS for a shared library are:
CFLAGS := -fPIC -Wl,-export-dynamic

fPIC - generates position independent code.The alternative is fpic which is not supported on all platforms.

-Wl,-export-dynamic - passes the export-dynamic flag to linker. This is required to support callbacks in the library.

The object files are linked to final library ELF with 'real name' as the filename. GCC with LDFLAGs achieve this. The necessary LDFLAGS for a shared library are: 
LDFLAGS := -shared -Wl,-soname,$(SONAME) 


3. Installing the library:
Copy the shared library file to /usr/local/lib and run ldconfig to install it. Add the path /usr/local/lib to environment variable LD_LIBRARY_PATH. Copy the library header to /usr/local/include. 


4. Linking to the library:
Compile the application with -l<name> and -I/usr/local/include.
Make sure you #include the header in the application code.

 
Reference:
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Git and Github - setup, workflow and learnings

Git has arrived and is here to stay. The learning curve is steep and frustrating. But the results are rewarding to say the least. I transitioned not too long ago from the simplicity (and accompanying inflexibility) of CVS. I can even hear myself groaning at the cruel change in terminology (commit is local... aaargh) and no direct means of applying CVS concepts in git. Sidenote: do not bother looking for git equivalence of CVS commands. I groaned until the moment I saw light.

The CodeChix ONF driver project collaboration would not have been easy without the power of git. But git in itself wasn't sufficient for our purposes - we also needed an online hosting service for the repository. We chose github.

Github has additional mechanism defined to manage collaboration in its hosted service which can be yet another source of frustration if not understood well - more on that later.

Specifically, we extensively used these features:
1. Fork
2. Pull request for codereview and merge
3. Pull from 'upstream'

The alternative to the above workflow is to clone directly from the project and push directly into it. I did not favor this approach as it does not allow for an intermediate step of reviewing the code. Pull requests are built for code reviews and explicit merges by the repo manager.

Here's the setup in great detail:
1. The main repo has a topic branch (called 'dev-onf-driver') apart from the master. This main repo with its 2 branches is our 'upstream'. You can set one or the other as the 'default' branch via the online github interface.

2. Fork - also executed online - creates a copy of the upstream in the collaborator's online github account. This is the collaborator's 'origin' and has both the branches.

3. git clone <path to origin>
Each collaborator clones the origin to their local development machine.

4. git checkout -b <branch name> --track <remote branch>
This step is necessary to clone any additional branches from the origin. The names/paths of all remote branches are listed in 'git branch -a'

5. git remote add upstream <path to upstream>
Necessary for pulling latest changes from upstream. The upstream (as noted in #1 above) is the main repo to which all collaborators will merge their changes via pull requests.

This completes the setup.

The typical workflow with this setup is:
1. Merging changes to upstream:
    Each collaborator does the following to merge to upstream:
      a. A series of 'git commit' followed by 'git push' when ready to merge. The changes are now updated in the collaborator's 'origin'.
      b. Login to online origin repo and start a 'pull request'. Edit the repo:branch combination to select the correct upstream and the correct origin branch. After confirming the changes displayed on the page, initiate the pull request.

2. Codereview:
    Every time a pull request is generated, it gives the opportunity to the other collaborators to review and comment on the code. The pull request can be cancelled or updated with changes.

3. Merge to upstream:
    Once the codereview is complete, the pull request is merged to upstream.

4. Pull changes to all collaborators' repos:
git pull upstream <branch name>
eg: git pull upstream dev-onf-driver
This is possible only after stashing or committing the changes in the repo. Once the local repos are updated, the origin needs to be also brought in sync with the upstream by:
git push

Our experiences:
1. Pull requests are *not* very intuitive. The pull in this context refers to pulling a merge branch. Pull in other git context refers to updating local repos with code from upstream. Getting pull request right in concept and in practice is a struggle and cause for many a mistake.

2. Collaborative merge permissions can be dangerous. It is best for the merges (from pull request) to be controlled by one owner. It is terribly easy to pull-req/merge with incorrect base and origin branches/repos. Reverting this is not as easy.

3. The only one way to update the online 'origin' repo is by doing a 'git pull upstream <branch>' followed by git push. There is no online mechanism to achieve that. This can be annoying but if the workflow is strictly established for changes to travel in uni-direction, this is not a problem. In our chase, the graph-edges were always uni-directional. upstream -> local -> origin -> upstream

4. git push to upstream. Like all things git, this too is possible but in a workflow like ours, dreaded!

What we may change next time:
Evaluate other means of codereview. Gerrit and Jenkins will be tested out for ease of use and cost. Pull requests are cause of many lost hours of productivity and will be avoided if possible.