Larry Price

And The Endless Cup Of Coffee

Everybody's Talking About Whiteboard Problems

| Comments

Interviews suck, amirite? Recently, there’s been a rise in posts discussing how harmful whiteboard problems are. Let’s chat about how the internet works, and then we’ll discuss where I land on this issue.

You’ve got one group of people who love whiteboarding. Whiteboarding allows interviewers to see how a candidate thinks. Whiteboarding gives the illusion of programming without the fear of compiler errors. Solving a problem algorithmically on a whiteboard is the same as programming.

And you’ve got the people who think whiteboarding during interviews is just as terrible as waterboarding a candidate. Whiteboard problems cause interviewers to become smug, sexist, and xenophobic. Candidates are forced to sweat bullets at a whiteboard while a death panel of interviewers silently judge them. Whiteboarding a programming problem is entirely different from computer programming.

Between you and me, I don’t believe it’s all so black and white. Like most things in this world, whiteboarding falls into a somewhat uncomfortable grey area. There are certainly things which can be gained by whiteboarding, but it’s also in no way indicative of programming strength or culture fit. There are literally classes teaching people how to be pro at whiteboarding.

One of the main problems is that this is not how you work in real life. You don’t put together code on a whiteboard while a group of strangers stares intently waiting for you to screw up so they can mark points off your score. Your day is largely spent reading other people’s code to figure out how you can force whatever new feature or bug fix you need to implement into their code as easily, quickly, and cleanly as possible, and then you’re usually put into a position where you have to sacrifice the easy, quick, or clean part of that plan. Along the way, you usually get to fight the compiler or search the internet for any relevant APIs, StackOverflow questions, or existing libraries. You’re probably also a member of a team with varying experience levels in the current codebase, so you’ll spend another big part of your day asking/answering questions on group chat and gatekeeping the codebase from code that is unreadable, unchangeable, or just plain questionable via code reviews.

But if this is the way we do our jobs, why do we ask candidates to reimplement underscore’s debounce function, create all the possible words from a telephone number, or generate roman numerals from an integer?

Some organizations have moved to systems of making the candidate solve a multi-hour problem in their free time, or come into the office and spend a day (or more) pairing with their future teammates. Although I think these ideas are founded on a solid base of logic, they are terrible. A large number of worthy candidates already have full-time jobs to deal with, and many of them have other commitments during the evening hours. The perfect candidate may have recently found themself with a new child, and every non-9-5 hour is no longer available to create a reverse binary tree. Adding more work and stress to an interview is not the right way to go.

How could we possibly find the perfect candidate without stressing them out and giving them standardized tests?

Let’s make them work like we do, but only for a reasonable amount of time. Come up with a medium-difficulty coding problem and write it yourself. But don’t make it clean. Make it sloppy. Make a ripe mess of that code. Add an obvious bug or two.

Now, when you bring in an interviewer or talk to them on a video call, show them this code. Can they figure out what it does? Can they find the bugs? Ask them to code review it. Do they see all the terrible things you’ve done? Can they tell you how to make it better? Can they do it without being condescending (news flash: most full-time programmers cannot do this)? This should all be a back-and-forth, with the (lone) interviewer working with the candidate to discuss any issues. If you have time, ask them to actually correct and refactor some of the code. If you’re into that kind of thing, work with them to write some test cases for the bugs you’ve fixed. If for some reason you still don’t know whether or not you like this person, have them add some functionality to the codebase. Then code review their code and see how they handle your suggestions. You should limit this exercise to an hour, maybe two if you’re a sadist. Do not make this an all day thing.

Think about how much you could get out of this exercise. You’ll determine whether the candidate knows what code looks like, knows how to read code, knows how to communicate about code, and knows how to fix bad code. You’ll also get a bit of their personality based on how mean they are during the code review sections. Hopefully, you were able to have a real discussion about design decisions and coding during the interview. The candidate will have done very little programming, just like you and me on a normal day. Best of all, you’ll only have spent an hour of each other’s time trying to figure out if the candidate is competent. Leave time for questions at the end and be done with it.

Of course, I don’t currently run a tech company or do much with the interview process. But everyone’s been giving their two cents on that issue, and I like to type words on the computer. What do you think? Is whiteboarding during an interview integral to your interview process? Do you need it? Do you hate it? Do you have any alternatives? Let me know in the comments.

Going Remote: 1 Week In

| Comments

I would like for this to be the first in a series of blog posts detailing my experience migrating from a culture based on co-location to a fully remote environment. Look out for another post at about the 1-month mark.

I’ve spent an entire week working remotely. How did it go? I’m not going to go into my current job here (if you’re curious: I love it), but I’m going to try to focus on the aspects of setting up a pleasant environment for working from home and how I coped during my first week.

But first: some background

I’ve never worked remotely as a professional software engineer for more than one day at a time until now. I’ve been a part of an office with traditional cube farms and an office with more modern team spaces. I haven’t worked in a Silicon Valley Sweat Shop, and I’ve never had a private office with walls, windows, and that holy grail of office furniture: a door. My past organizations have been nested in a culture of co-location which is, of course, very normal. However, I’ve very recently moved to a position at a new organization with cultural values borrowed from the open-source community. About 70% of the 700 employees are full remote.

When I use the term “working remotely,” I mean that a given employee works from wherever they want. For the majority of people it’s their home or apartment, but it could also be a coffee shop, a co-working space, a public park, or anywhere with an internet connection and a nearby power source.

Setting Up My (Physical) Environment

Also known as Things I Had to Buy to Make This Work.

To prepare for this new work environment, I did what anyone would do: I started buying things. I bought a cool wireless mouse that I could connect to my laptop through it’s built-in bluetooth. I bought a chair with a name from IKEA and one of those cheap plastic carpet protectors. I started looking into motorized sit/stand desks, but didn’t purchase one immediately (a mistake I quickly recovered from). I moved a second lamp into my home office and figured I was set up for success.

My first day, poor Markus (the chair) cracked the floor protector in several places, and my carpet is so thick that the chair couldn’t roll on its own. I painfully used my laptop’s keyboard for about 15 minutes before finding another mechanical keyboard to use instead which arrived that afternoon. The height of my old desk made sitting for hours super uncomfortable, so I quickly put in an order for a sit/stand desk that I could use downstairs where the carpet is thinner.

The next day, my new mechanical keyboard refused to let me type Shift+RightAlt without thinking it was a Meta key, causing all my keyboard shortcuts to be busted. I swapped it out with my old mechanical keyboard that worked just as well, but with a functioning Shift+RightAlt. It was around this time I noticed my WiFi connection was becoming flaky. I cursed my ISP and decided it was fine for the time being.

At some point during the week, the sit/stand desk arrived. Because of the thick carpet and uneven floors upstairs, I decided to start creating my new office downstairs. Unfortunately, my house is extremely poorly lit, so at the end of the day I had to run out to Target to buy a new lamp (and some cream cheese! classic combo!).

By this time it was Friday. My network connection was not just bad, but worse than it ever had been. I started sniffing around the internets and found that my wireless card (a bluetooth/WiFi dual card) was notoriously bad at handling bluetooth and WiFi at the same time on Linux, but sometimes updating the kernel and getting the latest iwlwifi drivers fixed the problem. So I updated to 4.3. No luck, so I updated to 4.4. Still no luck. By the end of things, I had the 4.4.6 kernel and I honestly thought things were a little better. A few hours and a dropped Hangouts call later, I realized I was wrong. However, booting off of a USB with fresh Ubuntu gave me a consistent and fast network connection. After piddling around a bit, I dramatically smacked my forehead. I flipped off the bluetooth connection on my laptop, and my network connection was fast and stable. I had been thwarted by my beautiful bluetooth mouse which, fortunately for me, also came with the usual wireless USB dongle.

At the end of the week, I finally felt like my setup was fine. Network still a little slower than expected, but I fixed that recently by moving the router to higher ground.

Let me count the ways…

OK, so I had some issues getting my home office in working order. But I love working from home.

I don’t feel rushed when I get out of bed in the morning. I shave, shower, make coffee in the french press, and perfectly toast/cheese my bagel; and I get to enjoy every minute of getting ready for the day. I start when I want, but when I want is a normal time. I’m at my desk ready to do my job sometime between 7:30am and 8:30am. The only way I need to let people know I’m in the office is by signing into chat.

My house is almost silent except for the noises I make and the infrequent meow of a cat wanting attention. I can focus on what I’m doing without being distracted by peers or normal office noises. I don’t need to put on headphones when I want solitude, which means I’m not distracted by whatever noise is coming out of the headphones. Achieving flow seems to be much easier when there are fewer distractions.

Speaking of cats… I know this will seem silly, but it’s quite nice to have my feline companions hanging out with me all day. Usually they’re taking naps nearby so I can say “d'awwwwwwww”, or they’re waiting in the kitchen for me to get up so they can get pets. Go adopt a cat now.

I can make a healthy meal really easily at lunch. I love being able to pull some frozen veggies out of the freezer, throw them in the skillet with some sauce ingredients, add some protein, and feel like I’m eating well in the middle of the day.

All of my communication comes through chat, email, and infrequent Hangouts. We mostly just use Hangouts for our daily standup, and it’s a great way to see everyone’s faces and feel like a team. Email is pretty much only used for mailing lists, such as new merge proposals, bug reports, and company news; so I only glance at my email a couple times a day, and mark whatever I don’t care about as Done. We use Google services to do this, which means I’m using Inbox to achieve zero-inbox. Chat is our primary means of communication. Being a remote group, the chat is extremely efficient. There are no graphic memes, and chats never end with “let’s get a conference room to hash this out.” Information is constantly being exchanged through the chat, and I rarely feel dissatisfied with the outcome. It’s also interesting to note that when you leave the chat, you do not get to know what happened in your absence. However, this does not seem to be a hindrance to anyone, but almost more of a relief. You don’t need to be in-the-know 24/7 to know what’s going on.

Near-Future Goals

  • Exercise more. Although my eating habits feel a little better, my exercise habits have been much worse. I used to meander the office every hour or two to get 10-15 minutes of exercise, or go outside to walk around. I have my sit/stand desk set up now, and I shuffle back and forth based on what I’m doing and how my butt feels, but that doesn’t count as exercise. I plan to lift my 10lb weights more frequently, and I’d like to work out my core with push-ups and bicycles. It would also be great to walk around the neighborhood in the summer.
  • Extracurricular. It’s been a while since I’ve worked on something meaningful in the evenings, and it’s been tough to get started on something since my work office (and computer) is now also my play office. In the next few weeks, I’d like to build an Atom.io package to integrate with bzr.
  • Personalize workspace. Since I’ve taken over the living room, the decor is mostly a big, decorative clock. I have some wicked posters I’d like to put up, but I need to convince my housemate that they won’t look too tacky in such a guest-visible area.
  • Find a better floormat. Like I said, this cheap IKEA floormat cracked on the first day. I’d like to find something vinyl or closer to rubber that will be more resilient but also more comfortable when I morph into standing mode.

Design for Real Life (Writeup)

| Comments

The Gist

Have you ever tried to buy airline tickets in a hurry? Have you ever had to find directions to the ER on the hospital website during an actual emergency? Have you ever wondered why you have to give a bug tracker your “title,” “gender,” or “address”? Design for Real Life written by Eric Meyer and Sara Wachter-Boettcher explores the pitfalls of designing for the perfect user and the dangers of asking unnecessary or inappropriate questions.

By the way, the means by which I found out this great book existed is by following Sara on Twitter: you should too!

Takeaways

We spend a lot of time designing our websites for the perfect persona. Right this minute, you probably have Sam the Salesperson, Hermoine the HR Rep, and Monica the Manager all smiling down upon you from their painter’s tape thrones on the wall next to your cubicle. You meet these caricatures at their best: bellies full of coffee, heads full of false worries, plenty of time, and a healthy dose of get-up-and-go in their web browsing digits. These idealized characters are a great way to make a best-case-scenario product, really nailing that “90%"of users everyone wants to find.

What about the other 10% of users? At the start of a long and miserable day full of meetings, can someone short on time and patience create yet another calendar event in the few short minutes they have available? Thirty seconds before Polly the Procrastinator’s timesheet is due, can she quickly add in her time without filling in meaningless fields? Instead of focusing on the ideal case, we might be better-served using this kind of time-crunched, ambivalent user as one of our personae. By designing for the streamlined user, we’ll likely find that we’ve also satisfied the needs of our “ideal” users.

We ask for too much information. Think about how many times you’ve just filled in junk information in forms to get through them as fast as possible. It’s not shameful; it just wasn’t worth your time to fill our information that you knew the application wouldn’t use or could potentially use against you. On another note, think about how many times you’ve given up filling out a form for a website because it was just too long. Asking for too much information causes user fatigue, and you are guaranteed to lose users when you start asking them for too much. If your website doesn’t need to take location, title, or city of birth to get its job done, stop asking for them. If you have a tough time removing these fields, then write some user-visible text explaining why you need this information.

Some questions could cause an unintended emotional response from users. If you’re going through a tough time in your marriage or a recent divorce, filling out “title” or “marital status” could cause unwanted emotional duress. A “gender” dropdown with two options is non-inclusive to users with a non-binary gender identity, and may cause users going through a transition to wince at such a question. Someone who has just suffered the loss of a parent, child, or sibling could feel great emotional pain when you, a complete stranger, bring up family members for no reason but to feed to your bottomless data pit. Once again, the first question you ask yourself should be whether or not you absolutely need that information. Again, if you really want it, consider making more fields optional and explaining how this information will help your application.

Do more user interviews before implementing newly-designed features. We can’t assume that everyone will use the app the way we think they will, and we’ll always be better off for getting more information.

Your app probably doesn’t need to be funny. We litter our error messages with “Whoopsie!” and our log out messages with “Sayonara, sucker!”, but this is an absolute waste. When errors occur, there’s a chance you’ve just angered your user. You know what makes them angrier? That error message you wrote that you found funny at the time. Be informative and supportive in your messaging, and your users will be better off for it.

Action Items

  • Stop trying to be funny in the copy. It’s only funny when developing. Maybe we should have some sort of i18n setting that shows funny messages during development and English in production.
  • Don’t ask so many questions.
  • More form fields should be open-answerable. Also more form fields should be optional. Also see previous bullet.
  • Streamline the hard stuff. It may not be the most-used feature, but if it’s important to a user in emergency mode you can bet it’ll be appreciated.

A Chronicle of SEP Startup Weekend 2016

| Comments

Last weekend was the 2016 SEP Startup Weekend, a bi-annual hackathon where a few of the engineers get together for 48 hours to build things. As far as most people know, we transform massive quantities of beer, coffee, and unhealthy food into cohesive piles of code. Although that about sums it up, I thought it might be nice to chronicle my team’s experience of this season’s event. Enjoy!

The Pitch

In my first startup weekend since Ollert, I pitched an idea for an instant runoff voting platform called RePoll. RePoll would allow users to create polls, rank candidates, and view results in a login-less system via a web portal, Android, and iOS app. To make it all interesting, I wanted to do all of the coding in javascript by using React for the web frontend and React Native for the iOS and Android apps.

Friday

I somehow convinced 3 of my coworkers to help me on Friday night, who I’ll refer to as H, G, and K, forming teams by combining the letters.

After sending around a few images and documents with my proposed architecture, I had GH start working together to build the Android app in React Native. Unfortunately, we hit a few snags in getting React Native to run an Android app on actual hardware, but late into the evening everything was up and running on a genymotion simulator. By the end of the night, GH had a good portion of the React Native opening tutorial completed.

In the meantime, K and myself were hard at work building a core web API in NodeJS for all apps to use. We decided to use Mongo so we didn’t have to worry about updating schema and initializing databases, and we used Postman to test our API calls. I may have overarchitected the session/token-based authorization system, but we got over 50% of the way done with the API. In my initial estimates, I wanted to have the API 100% completed by Friday night, but we were all tired and decided to break for the night around 10p.

Although everyone else headed out the door, the garage was packed with cars leaving a fancy-pants event held near our office. I stayed behind for about an hour setting up our API to run on heroku with a MongoDB instance, and then configuring DNS for the domain I had already purchased.

Saturday

I arrived early and laid down some sweet jams. I continued working on the API alone and had K start working on the iOS app. We added a new teammate, dubbed A, who started work on the web frontend. The API neared completion by the end of the afternoon, and the mobile apps were beginning to hook into the publicly accessible API. During this time, several bugs were found in the initial API code and were fixed. The iOS app was making quick UI progress, but having issues connecting to the API. I started floating between dev teams as I got drowsy, but eventually got a second wind and started helping with the web frontend. The Android and web applications were both able to create polls before everyone went home. A started using a web React datetime component to set start and end dates, while the Android team was figuring out how to use the native calendar and clock to select dates and times.

To store data, the mobile teams started using the Async Storage library which allows for OS-agnostic storage of data in iOS and Android. On the web frontend, we used local storage to keep around any information we might need.

Near the end of the night as I started working on the poll results page on the web frontend, I started finding system-crashing bugs in my interpretation of instant runoff voting, and eventually found that the results weren’t always correct.

One item slowing us down Saturday when writing React Native code was its insistence on using syntax defined in ES2015. Our team was largely unfamiliar with this new syntax, so this tripped us up a bit more than expected. All in all, it was a great learning experience to see this cutting edge specification in action.

Sunday

Early again, I created a heroku app for our web frontend and set up the DNS appropriately. As the rest of the team started to pile in (and the smells of bacon arose from the Commons), I transitioned to trying to fix the incorrect ballot-counting logic in the API. I ended up rewriting the code several times, but finally found an algorithm that worked correctly. At this point I was kicking myself for not writing tests to verify we were writing good code.

The Android team caught a second wind, finishing the create poll page and started tackling poll lookup. The original plans called for a typeahead, which ended up being tougher to implement than expected, so the Android app instead supplied a simple textbox to attempt to match an existing poll. In doing this, the Android team successfully created an authentication token in the API and was able to display poll candidates in the app before running out of time.

The iOS team continued to have issues with the API, but successfully mocked out most of the rest of the app right before the demos.

Due to familiarity with the tech, the web team was able to get most of the way to a completed layout. I hastily fashioned a dual-list system for seeing candidates and ballot selection, while A transformed that system into a drag and droppable component. We were able to submit updated ballots to the server and fetch previous ballots for our poll tokens. With the updated API, the results page started working and it became possible to view the steps involved in eliminating candidates during the runoff process.

During demos, we presented all three apps and everyone was quite impressed at our javascripting.

Action Items

  • General Things
    • Learn more about React Native. I was largely shielded from the pain as I was working on the API and React web parts of our project, but from what I’ve seen and heard React Native is an incredible framework for getting things done and sharing code and code paradigms.
    • Start using ES2015. Tools like Babel allow us to start using next-generation javascript standards to write code now even if the browser support is unavailable.
    • Do more with webpack or browserify. I want to be able to use these tools to optimize pre-rendering on our site, but we were in such a rush we primarily used webpack to enable us to use several NodeJS dependencies. Still cool, but there’s so much else to explore.
  • Startup Weekend
    • Estimate better. I drastically underestimated the amount of work needed to get this project completed in a weekend. We would have had a better chance had I pre-built the API. I think doing some pre-work in this case would have been okay, but I also could have asked for more help. Next time I would like to do a better job of figuring out how much work there is and how much time it will take.
    • Be an expert. About half the work we did this weekend was in unknown territory for me. I should have studied further on getting React Native working before the event, and I should have known a little bit more about ES2015 as well. Although the lack of expertise slowed us down a bit, my teammates were extremely adaptive and loved learning the new tech.
    • Create and prep the team beforehand. I had enlisted one engineer before the pitches Friday night, and I ran my presentation through that engineer to verify it all made sense. I should have also run some of my architecture ideas past that engineer to get buy-in. I also wouldn’t mind having the team mostly formed before we start, but that’s a big commitment to ask of people.
    • Take more frequent, shorter breaks. We hit the Monon Saturday afternoon and walked for 30-40 minutes which ended up making me drowsy. However, the fresh air did us some good and was revitalizing for the project in general. It would be great to have more frequent, 10-15 minute walks, but it’s really difficult to find a time when the team is ready to take a group break in such a fast-paced environment.

Drive

| Comments

Have you ever seen a six-month-old or a three-year-old who’s not curious and self-directed? I haven’t. That’s how we are out of the box.
– Dan Pink

The Gist

Daniel Pink’s Drive explores how to motivate modern humans. Today’s offices still employ business practices created to meet the needs of late 19th and early 20th century workers performing monotonous tasks, but many modern workers spend their days doing creative work which is ill-suited for stick-and-carrot management. Pink posits that today’s workforce crave autonomy, mastery, and purpose to lead a satisfying life and produce better, maybe even faster, results.

Takeaways

“Stick and carrot” refers to the technique of “if you do this, then you’ll get that” motivation. Work overtime this week and I’ll buy you bagels on Friday. Read a book and you’ll get a free personal pan pizza. Sit, good boy, here’s a treat. Alternatively, “now that” rewards are ok from time to time. “Now that” the team has worked well together for a few weeks, I decided to bring in some donuts. “Now that” we handed off the code to the client, let’s go get lunch. Note that “now that” rewards should not become predictable, lest they become “if then” rewards.

The concepts in this book are not new. Researchers have discovered this kind of interesting behavior since the ‘60s, and each time they are essentially ignored by the general population. Over the last few years, I have read several books on this topic and assumed we were only just starting to realize that sticks and carrots were bad for creative work, but it seems to have taken some time for these concepts to enter the public view.

“Flow” is the optimal state of working, where the work is challenging enough to keep one engaged but familiar enough to allow mental connections to be made. It doesn’t mean working on something so easy one can get it done fast, because such trivial exercises are boring and non-enriching. Alternatively, it doesn’t mean working on something so difficult that one is “head down” for several days accomplishing nothing, because this type of task is exhausting. You’ll know when flow has struck when you glance up at the clock and suddenly an hour has gone by and you feel good about what you’ve already accomplished and you can see what you’ll be accomplishing in the next hour.

Although money is a poor way to motivate workers, all workers should still be given a fair base pay and benefits package. Everyone needs to live, and unfortunately we don’t live in a Roddenberry socialist utopia where everyone works together to build a functioning world where everyone is paid in the love of one’s career. In fact, Pink prescribes that organizations should try to pay employees slightly above average, which should essentially take the money issue off the table during recruiting and retention.

The best motivation in the modern workplace is the encouragement of autonomy, mastery, and purpose.

Autonomy is the ability to make decisions for oneself, and cause a meaningful impact on the work being done. The craving of the modern human for autonomy can be explicitly seen in the rise of agile software development, remote working, Etsy retailers, startups, farmer’s markets, and freelancing over the past 20 years. When people are allowed to make decisions without the intervention of big brother, they feel more ownership over the work they do, and they feel more freedom to be creative.

Mastery is continual improvement. A 5K runner achieves her goal of finishing in 20 minutes and sets a new goal for 19 minutes, then 18 minutes, and so on. She never stops to say “20 minutes was good enough, I think I’ll stop now.” Mastery is usually something that can never 100% achieved, but the quest for mastery is something that drives us to be better than we were yesterday.

When we think about purpose, we think about leaving our mark on the world. For some organizations, this may involve redistributing part (or all) of the annual revenue to charity. It could also mean building a better medical device for diabetics. Not all purposes are created equal. Improved quarterly sales, more working hours, higher profit margins, happier stockholders are all invalid purposes that do not drive workers to be happier.

Schools suffer substantially from our system of numbers-based achievements. Better grades and better test results have become the primary indicator of success, quelling the curiosity of our children and destroying the happiness of our teachers. Getting away from numbers-based learning will be an extremely difficult task, but there are already schools working towards this goal.

Action Items

  • Recognize when I’ve been in flow and write it down.
  • Recognize when someone is offering me an “if-then” reward, and try to determine a better way to think about it.
  • Recognize when I offer someone an “if-then”, and think about the consequences. Did they perform better or worse than I expected? How could I have created an opportunity for the other person to improve themselves instead?