Scoring Intern Puzzles

I recently got to score coding puzzle solutions submitted by a crop of students who wanted to be interns for my company. Overall, I scored six puzzles and gave two passing grades. These were applications generally submitted by rising Juniors and Seniors, so I had fairly modest expectations about the overall quality of the solutions they would be presenting. I wanted to see some basic object oriented design, usage of the proper data structures, and correctness in a couple edge cases. The issues with the failures varied, but the most egregious and common issue was a failure in understanding object orientation. The typical solution was a java file, with one class generally nothing but static methods and everything public.

This led me to two immediate thoughts: are these students horribly unprepared or am I expecting too much? I went and asked one of the engineers who had scored another batch of solutions about what he got. His batch was distinctly better, one even had unit tests, but there were still some significant duds. The conversation attracted two recent grads who took a look at some of the solutions, and also thought they weren’t that good; since they were closer experience-wise, I thought that their expectations would be more reasonable. I know that they are getting a computer science education not a software engineering education, and I had talked about this difference before, but they need some ability in computer programming to demonstrate their computer science skills.

I tried to think back to when I was in school and what I was like at that point. I know I didn’t have the best practices then, but I feel like I was ahead of where they were. I wish I still had some of the code I had written then to look back at and compare. I don’t think I was great at that point in my programming journey. But, I feel like I would have at least put together a class or two as part of the solution, even if they weren’t really needed,  just to show I could decompose the problem.

I suspect that since internships have become a significant need that students are pushing out applications and doing this puzzle is a hurdle to them doing yet another application but they don’t recognize how to optimize their solution to show off their skills. Each solution had some positive aspects, but were missing most of the aspects I wanted to see. To me this meant that the skills were being taught, since they had all picked up some of them, just not enough of them yet.

Career Goals

I’ve never been much for setting goals in my career. I’ve always taken problems and solved them, but never had much of a long term plan for where I wanted to go. I’ve always been interested in the architecture aspect of software engineering. But that always felt to me more like a role, and while you can have a goals to be involved in that role it isn’t a terribly productive goal in of itself.

If a goal is a SMART style goal where it is something you can actively work towards, then you can just do it and know that you’ve achieved it. But something like being “more involved” in the architecture aspect of a project isn’t something you just do on your own, or necessarily know when you’ve achieved it. To be measurable and achievable, that sort of abstract goal needs to be broken down into smaller portions that can be achieved independently. It always seemed to me that the more interesting sorts of long term goals of this nature are difficult to break down into individual aspects.

To move myself towards that goal I’ve done most of the architecture tasks for whatever team I’m on. I’ve also been actively volunteering to help other teams with their architecture problems – just as a second set of eyes. None of this really ever got me progress towards the goal of being able to work on architecture full time. I had spent a lot of time trying to come up with other specific actions to try to advance me towards this goal.

Today, I had a realization that maybe I was looking at the wrong goal. I don’t want to do architecture most of the time, because I don’t want to be in an organization that has a role where someone does that for others. I want to have the ability to pick and choose my own projects, and even define my own projects to solve problems others may not have even recognized as problems yet.

This got me to thinking what sort of intermediate goals I should be working towards for this larger goal. I haven’t been able to come up with any of the intermediate goals/actions thus far. Some ideas I’ve considered so far and rejected: being superiorly productive, being vocal about any issues I see that need attention, and just doing what I think is right regardless of what’s on the team’s agenda. Being superiorly productive was rejected because it would mean that I need to stop spending as much time helping others with their problems and therefore collectively putting out a less solid product. The issue I had with being more vocal was that I would inevitably be bringing up problems that I didn’t have a solution to or did not have time to do anything about, which feels like it would just seem like complaining. Just doing the right thing and ignoring my team’s mission is difficult since it puts me and my team in a complex situation in that we aren’t doing our specific part of how the organization is supposed to work, but if we solve another problem it might be okay, it also requires the ability to go your own way long enough to have results to show.

I’m still trying to work through the ramifications of this personal epiphany, so I haven’t taken any real action on it yet. I don’t know if I will be able to figure out a new course of action based on this, but I hope to.

Propinquity

Propinquity can be described as the rather obvious idea that you interact more with people near you. Not just physical nearness – it also encompases mental nearness like shared beliefs, common experiences, or a shared ubiquitous language. This comes up in software development in a number of different ways. Propinquity is teams that are more efficient because they understand each other and the domain at a deeper level. It is a team that intimately understands each other and the domain. It has negative expressions too. You get software ecosystems that become insular and don’t integrate new ideas. It is even sexism and racism. It is an unconscious bias that influences the way you think about things.

Recognizing propinquity can help you overcome your negative biases, build stronger teams, create solutions to your hardest problems from outside the box. Team culture is propinquity – it can be good forming bonds between coworkers, it can be bad when the team looks for people like themselves and ends up rejecting the best candidate because they didn’t have a strong enough resemblance. This can also be seen as a kind of implicit bias; when you start to think of the discussion of diversity in the workplace in terms of propinquity, it starts to mean something different.

I recently heard an interesting discussion with Leslie Miley of Twitter on a podcast (starting about 12 minutes in) about how the lack of diversity at Twitter could be negatively impacting their ability to solve problems. His thesis is that if you hire everyone with very similar backgrounds that they will all look at the same problem the same way and come up with the same solutions. They would then miss the same things, and get stumped by the same problems. This is why you often get great solutions from people outside of the problem, because they are looking at the problem from a different perspective.

I don’t have much insight into how other professions interview people, but in software it seems like the interview is more to determine if you can do the job than if the applicant is the person you actually want to be working with. But the way we go about determining if you can do the job is to ask questions that you don’t truly need to be able to answer to do the job, but implicitly reflect schools of thought on how the job should be done. If you ask a question about red-black trees you are looking for someone who had a computer science education; you aren’t expecting anyone to build a red-black tree but you are using that as a proxy for having been exposed to certain ideas. If instead you ask questions about TDD or design patterns it says you are the kind of people who care about those ideas instead and have less of an interest in computer science fundamentals and optimizations.

I went on an interview previously where they asked lots of low-level questions. The job had nothing particular to do with those skills, but they felt that those skills were what differentiated good programmers from bad ones. Their understanding of what makes a good programmer is that you can twiddle bits and will micro-optimize solutions. The interviews we gave at a place I used to work were focused on design patterns, which  was the language everyone there shared. At that job we didn’t have the low-level optimization skills to find a particular optimization that would have been a big win for an ongoing performance problem.

This ties back into the post I had on evolution of the javascript ecosystem. The ecosystem has propinquity in terms of javascript language itself, but has diversity in that most of the developers came from different stacks with different backgrounds. This level of creativity is what can be achieved if you balance propinquity and diversity against each other well.

Propinquity looks like culture superficially, but it really is a double-edged sword: a team that intuitively understands each other, but blocks out other perspectives that could be valuable to solve problems better. The values espoused by your organization are all about creating a culture and a shared experience to build the positive aspects of propinquity, but the negative aspects can appear too if not kept in mind. The different aspects of what an engineer looks like can’t be too rigid, otherwise you reject great candidates for lack of a degree, or interview for markers that imply competence but aren’t competence themselves. Conversely diversity is more than ethnic diversity – it’s diversity of thought. You need people who think in design patterns and people who think functionally and people who buck the trends of what you are doing right now.

Ideally you could get people who can do all of those things. That’s obviously not a realistic way to do recruitment. You want people who fill in your weak areas, ideally creating something like this.

overlapping

It represents the whole organization and how each individual’s competencies overlap but are each valuable. Each individual is close enough to the others to have some propinquity, but the whole group embodies the diversity you would want to get different viewpoints on problems. Conceptually with smaller units you can also look at this as a radar chart, if you map out where your team is currently strong and where it is currently weak, you see where you need help and where you don’t need as much, but it’s still hard to find the right way to find that person when they look different, and may not be in your normal talent pipelines.

Even just considering these sorts of issues points you in the right direction. If you consider that the person you are looking for is different than those you have, you might be willing to ask different questions or judge the responses differently.

Book Chat: The Senior Software Engineer

The Senior Software Engineer by David Bryant Copeland is a manual for being a Senior Engineer and covers all of the things nobody bothered to tell you about. For me, it’s all of those things that I put together from reading dozens of blog posts and watching those senior to me do the job. Most of the book was the description of what the role is and describes it in sufficient detail to help an engineer who has not yet achieved the role to target the experience to show they can do the job. It is the sort of description of the role I would have liked to have gotten from a manager early in my career.

Since I’ve been doing the job of a Senior Engineer for years now, most of it wasn’t particularly novel to me. However, I would have liked to read this before I made the transition to Senior Engineer. It differentiates between building a new feature, fixing bugs, and solving problems, which are what I would describe as the three main technical components of being a Senior Engineer. It also describes quality technical writing, working with others, making technical decisions, interviewing job applicants, and leading a team.

Interviewing is probably one of the most critical areas that you don’t get a lot of exposure to before becoming a Senior Engineer, and it’s pretty well covered here. Copeland lists four components to the technical interview (in order):

  1. Informal get-to-know-you conversation
  2. Homework assignment
  3. Technical phone screen
  4. Pair Program

It seems like the phone screen should go before the homework assignment, especially if the assignment won’t be the focus  during the phone screen. I actually interviewed at a place where the author was working some years ago and the interview was significantly different than what he described. There was no informal conversation, no homework assignment, and no pair programming. There was a phone screen and a white boarding session. I suppose he may not have had total control of the process there but it is interesting to see the difference between the ideal and the actualized.

If you are looking to become a Senior Engineer and get a grasp of all of the aspects of the job before trying it, this would be a good read for you. If you are a Senior Engineer I’d pass and try something else. It might also be good read if you are a manager and looking to find a way to articulate some of these ideas to your junior team members.

Flow and Learning

Since I recently changed jobs, I’ve been learning a ton of new things. Moving from Windows/C#/Visual Studio/ASP.Net/SQL Server to OS X/Scala/IntelliJ/Play/MongoDB is a lot of change, normally you’d have some sort of strong point to leverage off of, but for me it is all new. I’ve always had an introspective personality, and the introspective part of me is looking at this and thinking that I got in over my head. The logical portion of my brain says the learning curve is expected and I’m working my way up it, but it is difficult to reconcile the two perspectives.

slide41

I had found the above diagram describing how challenge and skill interact and can cause boredom or frustration. The context of this diagram was how games try to stay in the flow channel, and the player response on either side of the channel. The more immediately relevant version was the one where it described the experience of starting a new job.

slide17-1024x7081

This diagram matches with my experience here, especially since I took a bigger hit to my applied skill level due to the radical change in the technical stack. This puts me further into the frustration section than other similar job change experiences, and causes the sort of anxiety that I had been grappling with.

I know I’m making sure to keep an eye on my stress levels and everyone at work understands the challenges that are being encountered since they went through most of the same ones at some point. I changed some of my habits around what I’ve been reading, less dense material more fiction. I changed some other habits, since I cut my commute down significantly I’ve been trying to make sure to use that time wisely and get some additional exercise to deal with the stress in a positive fashion.

By putting together the rationalization of what is happening I hope to assuage my own insecurities. The mental load of the insecurities can take attention away from learning and doing your best, making the insecurities a self-fulfilling prophecy. I hope this account of the feelings I’ve been encountering helps others to recognize that they aren’t anything abnormal to feel, but that you can’t let the negative feelings control your mind.

Thinking Back and Looking Forward

I’m writing this after my last day at my previous job. It has me reflecting a lot on the three years I was there. I learned some interesting things and met a lot of great people. There were aspects of the job I really loved, and there were the aspects of the job that I would love to never think about again. I was reflecting back on my accomplishments there and I was surprised how much I had done in some aspects and how little I had done in others.

One of the memories that stuck out to me was the response to some production performance problems we had in July of 2014. I was new to the organization, which made it my first chance to see how it responded to a crisis. I learned a lot about the organization then. It was great to see how disparate teams came together and worked the problem. It also gave me an opportunity to better understand the organizational structure, good and bad. While investigating, I ended up digging into something that wasn’t the cause of  the problem, but demonstrated numerous other little problems that had been festering. There, I managed to make a big impact with different higher-ups once I showed them all of the hidden problems I dug out. It was especially interesting for me to handle from a workplace navigation perspective, since all of the problems were outside of things my team was nominally responsible for.

An area where I tried to make an impact and spent a lot of effort was the build pipeline. The ‘continuous integration’ that was set up by the configuration management team had numerous problems. The basic workflow was that they would – on request or on a timer – take C# code, compile it, and commit the DLLs back to SVN. When I first saw this, I noted that using source control to store the binary artifacts that were created from the repo was odd. The configuration management team didn’t have any interest in changing this, since the entire deployment process was based around deploying DLLs from SVN; it’s understandable they were resistant since changing this piece would require changing everything. This limited a lot of my options on how to change the build pipeline without getting involved in deployment as well. I spent a long time trying to convince the configuration management team to run tests before committing back to SVN, but the server they were building on failed a number of the tests when they tried that. It turned out that the team that owned the code under test didn’t even know those tests existed. This led into an effort to find all of the tests in the whole system and get them passing again. We made progress on these goals but there ended up being a functional area nobody owned, and the rest of my team didn’t feel like we had the capacity to take ownership of it. This left the effort in a sort of stalemate: progress had been made and we could run a lot of tests, but there couldn’t be a clean build unless we started making exceptions. We held in limbo for months, where management continued to debate  who owned that functional area. This eventually led to the effort dying off. That was a massive blow to my morale, since to me it implied a lack of focus on quality; that wasn’t at all their intent, but that doesn’t reduce the frustration after I had gotten so far and made so much progress. I recognize that I may have taken it too personally or read motivation into it on management’s part that wasn’t there, which is an important lesson I’m taking away. I also learned a great deal about how to navigate the corporate environment and how to use soft power to influence change, but most of that was too late to make this change successful; now I know better how to approach this type of major change management from the start.

I don’t want to give the impression that everything was bad – a lot of aspects of the work were great and interesting. I had a great experience working with a system that is much larger than anything I had worked with before. The whole system was hundreds of times larger in terms of computational resources than anything I had worked on before. The codebase itself was approaching ten million lines of code across 10+ different programming languages. Digging into all of this was an amazing adventure to understand how it all went together. Very few people were looking at the system as a whole and I got to come in, learn and understand all of this and help those who were trying to build other pieces of it.

I also had the opportunity while there to mentor some junior engineers and it was quite rewarding. I helped them get up to speed on the code base, which is an easy enough activity. But I also spent a great deal of time working with them on code reviews and helping them understand how to build better software. Helping them to understand the difference between something that works and something that is truly good was really rewarding as they started to see the difference.

My new job is a much different situation than my last job. At the last job I was there to help them clean up the technical mess they knew they had; their issues are common to large organization that have grown through acquisition, and I do appreciate that they wanted to improve. The technical mess wasn’t the whole problem; as you can see from these two anecdotes above there were multiple groups who weren’t in sync and a lack of understanding of each other. The new place is much smaller so it’s unlikely that I’ll have to navigate as many different competing groups, or be assigned such a narrow portfolio. My new company is also much newer so there hasn’t been the time to build up the layers of technical debt. From a technical perspective, at the new job I hope to master a new language and stack and build out some RESTful web services. I’d also like to help build a high performing team and mentor some junior developers, since I found that  really rewarding The person who mentor me to see that difference between “works” and “good” happens to be working at the new place, so that will be a great relationship to renew now that I’ve had an opportunity to play that role. Sometimes the journey is the destination afterall.

Starting Scala

I’m starting a new job soon which is going to be entirely Scala programming. I’m trying to dig in a little bit and get started with a leg up. I’m going to outline my basic plan here and post updates as time goes on. I’ve done a tiny bit of Scala before when learning some about Spark. I’ve done some Java work in the past as well so the ecosystem is a little bit familiar. So I’m not coming in from nothing.

The place I’m going to be working uses Macs so getting off of Windows seems like the right way to get started. I had previously used Eclipse when working on JVM based languages. The last time I had used Eclipse though it seemed like more had changed than was the same as I remembered. So I’m going to take a different tack this time and try IntelliJ. So the overall development environment is going to be an Ubuntu VM and use IntlliJ on it.

I plan to start with Scala School to make sure I’ve got all the basics down. Once I feel I’ve got that put together I’ll try Scala Exercises for some more guided exercises. Then I’m going to do some of the Project Euler problems I had done in F# since I understand the problems and can focus on learning the idiomatic Scala way of doing things.

I figure this should get me up to speed on Scala pretty quickly. We’ll see how well it goes.

Hiring Randomness

I ran across this article on companies’ interest in interviewing different archetypes of programmers, e.g., “Academic programmer”, or “Enterprise programmer”. I had two big takeaways from the article. First, all of the companies were different, so none of the archetypes appealed to everyone. Second, the archetype that received the most attention wasn’t the one described in terms of technical abilities, but in terms of the applicant’s interest in product development. The typical software engineer only hears interview feedback about themselves in relation to an individual employer, as opposed to hearing how different places consider the same set of people, so this was an interesting discussion to read.

The first insight, that different companies want different things, seems to have matched my intuition from years of moving around the industry. Each company seems to be looking for a different mix of skills and weighs technical versus soft skills differently. It’s really no different than the idea that different people look for different things in employers. When a job posting is put up, it discusses the technical and soft skills the role would want, so it filters the incoming candidates to people who think they match those. So, even on the inside, as an interviewer, you won’t see candidates who are self-selecting against the description of what you say you want to remove themselves from your potential hiring pool.

The second insight was more interesting, that the archetype that was described as about building product more so than building good software was the one that got the most positive response. This might make sense when you look at the audience viewing the archetypes in this particular example: small startups that need product. This archetype seems great, but why is there so much more interest than any of the other archetypes? I can see why most companies would want that archetype, but it isn’t clear why there is so much less for some of the other archetypes, who I feel like I would want to work with more.

There are some other interesting thoughts buried in the grid of results. The difference between the “child prodigy” and the “strong junior” archetypes are interesting. They both represent the same sort of talent, but with a different story, so why should there be a significantly different opinion of the two archetypes? Who is the company who rejected every profile but the enterprise programmer? Why would you take the “experienced and rusty” archetype over the “technical programmer” archetype? All of this taken together makes it seem like there is more at play in these discussions than just the background of the person being seen. It also seems that each company rejected about half of the candidates.

This led me to reconsider some of the steps I’ve used in hiring in the past. The shape of the funnel used in the hiring pipeline reinforces some of the built-in problems with attracting talent. It seems like the funnel is always too wide, pulling in candidates you can’t work with, and the resume screen is tossing the wheat with the chaff. The article’s advice to programmers seems to be to spend more time on each application and personalize it. This is good advice for the individual, but it doesn’t resolve the issue on the company side that everyone seems to be throwing away talent that some other company seems eager to have. That half is up to us when we are on the hiring side of the table to take an open mind to the background and find the talent that is interested.

Pair Programming Interviews

I had an interesting experience with a pair programming interview recently; it was conducted very differently from the other ones I had been on before and I want to explore the differences between them. Pair programming is a great way to solve problems and it makes for a good interview too. As an interview, it gives you insight into the problem-solving process and the social aspect of working with someone. It is a great way to see them do what you want them to do day in, day out.

The ones I had been to before had worked like a normal pairing session. We had a problem and worked together to solve it. Give and take. Since these were interviews I was driving probably two-thirds to three-fourths of the time, not the normal fifty-fifty split you would expect in an on-the-job session. I had always enjoyed the experience.

This most recent experience I had with a pair programming interview was quite different. The partner wouldn’t actively contribute to resolve the problem. If you asked a question they would answer it, but they didn’t drive at all, and didn’t proactively contribute to the task at hand. This was especially confusing in the afternoon session, which was set up to be done in a programming language I had never used before – by design. I think it was actively trying to push the applicant out of their comfort zone and see how they would react.

It was an interesting experience, and I got to learn a little ruby programming. I would definitely do another pair programming interview. But I feel like I would react against this sort of pseudo-pairing vocally if presented with this again. If that’s how they pair, I wouldn’t be interested in the job. If it’s a behavioral test, I wonder what sort of day-to-day activities they are engaging, if this is the kind of test they think would give them good information. The whole experience turned me off during the interview.

If you haven’t done any pair programming grab a partner and give it a try. Pair programming is a lot of fun, and helps you solve programs in a new way. If you already pair program regularly consider adding it to your interview circuit, but really treat it as a normal pair programming session.

Recruiters and Jobs

 

In the DC area, tech recruiters seem to be a fact of life. Late January into February always seems to be a very active season. The manner in which jobs are presented by recruiters makes me wonder about the state of the industry. Maybe it’s a DC thing, but I get calls offering 3- or 4-month contract work a couple times a month, offering really low rates. I don’t mean low for my experience level but low compared to cost of living. I’m trying to understand who is offering or taking these contracts.

There is the old adage that everyone hires the top 1% or 0.5% of programmers. Does that mean that 99% of programmers are no good? Not at all, the same people who are not employed currently are out there sending out resumes and staying in the market. It means that there are all the same people out there spamming any job opening. If you think about the inverse there are those jobs out there that everyone passes on, the job equivalent of those programmers who nobody is interested in. These jobs nobody is interested would be these odd contracts.

The different kinds of jobs are for different kinds of people. But sometimes it seems like the recruiters forget that there is a symbiotic relationship between the developers and the recruiters. For example today I got two calls from the same agency about the same job I wasn’t interested in hearing about. The second knew I had talked to the first recruiter and seemed intent on trying to address the reasons I told the first recruiter I wasn’t interested rather than extolling the benefits of the job.

The relationship between developers and recruiters needs a better defined rulebook. The current rules seem to be defined by the low end of the spectrum, where there is enough money to be made moving people around and putting butts in seats. I ran across a blog post about what recruiters should know about reaching out to software developers, and it resonated  with me. It described the issues I had seen where the recruiters just seemed to be offering the same job over and over. Do you have 10+ years of experience with Java EE, spring, bootstrap and jquery? Nothing about what you would be building, nothing about why you should want this job. Just that it’s there and you should want it since it is something.

The recruiters need to sell the job, and understand the uniqueness of that job compared to the other jobs in their current portfolio. This requires a lot more effort on the recruiter’s end to start with, but the longer-term payoff would be much more valuable. You develop a longer-term relationship with the clients and I know I would appreciate that sort of interest in what I wanted as opposed to a person calling me on a keyword match on a resume. My realtor has a stronger relationship with me than most of these recruiters are interested in. Expect better and you might just get it. I’ve had a recruiter send a handwritten card to try and stand out from the pack, and it worked. I read that card and thought to myself ‘This is a unique opportunity thought out for me.’

It will take a long time to get rid of recruiter season due to how it ties into budget cycles. But it would be nice to be respected as a person, rather than placed as a resource. I’ve asked some recruiters that called recently and given a weak pitch of a job, and I told them as much. The best thing you can do is to put direct feedback into the system. If they consistently hear that people want more than a three sentence description of the technical needs they’ll hopefully have something more valuable than that.