DevNexus 2018 – How to Hire Good Programmers

Title: How to hire good programmers
Speakers: Jennifer Bland

For more blog posts, see the DevNexus 2018 live blogging table of contents


Propose: Stop doing at home programming challenges

Problems

  • We don’t write new projects from scratch all the time at work.
  • Standing up an environment/project from scratch isn’t representative.
  • Being given 90 minutes to do something doesn’t count setup time and then judging them on code
  • [there’s also the problem that you don’t know if someone else did it and that you are expecting them to spend a lot of time on it]
  • [I like http://collabedit.com/ for a short at home exercise so can do real time and watch]

Propose: Implement short coding exercises – 10 lines or less

  • Assume 90 minute interview [I have shorter interviews]
  • Break questions into four areas of 15 minute chunks each. Pick four technologies that you use. Ex: html/css, core javascript, node
  • Goal of each section is to determine level of knowledge person has on that topic
  • For each chunk, ask questions.
  • Type 1: Test knowledge – traditional question. ex: what is difference between x and y. Start asking basic questions and ramp up.
  • Type 2: Write code – give structure and write code to do simple task. Ex: write a selector. Then make question a step harder. And so forth. [these questions are easy. I guess the target is for an entry level or junior developer?]
  • Scoring – set points for different levels of answer to each question and require minimum score to hire.

Propose: Casual tech discussions

  • Propose spending 30 minutes on this section.
  • At lunch at a conference, know people’s names, employer, where they live, what tech stack they use, etc.
  • At an interview, can find opinion. Do they have an opinion. Are they passionate. [I do this]
  • Allows candidate to be open, show understanding of topic, etc.
  • Goal: learn how person will fit into company
  • Also open ended questions like what online resources use.
  • [I thought this was going to be about having lunch with the candidate vs asking questions that are opinions.]

Q&A

  • What steps are in interview process other than the 90 minute interview? Post job and view resumes. HR will talk to the person first. Then spend a day and interview 5-6 people in one day. Usually half are “nos.” Then 1-2 strongest candidates and maybe someone close. Bring back the top couple and bring them back to write more code. Maybe 12 exercises in an hour where there isn’t enough time to complete all of them with half more common. You can see which ones they picked to determine strengths. Can have an offer in a a week. [that sounds like it assumes everyone is free to come in on same day]
  • Have you ever tested interview process on current team? No. But comparing candidates to each other. [I tested some of my questions on some teammates to ensure they aren’t too hard]
  • Do you recommend having candidates pair with current employees? Haven’t tried.
  • How batch candidates? Run job ads for two weeks. Have people come in over a week. It’s the second level where they come with a day or two.
  • How mitigate against people who can’t write code? Asking them to write code. Testing how they problem solve too.

Note: she works for and R&D division of Black and Decker. I imagine that gives them overall stronger candidates.

My take

I definitely agree with not giving a 90 minute project to do at home. I agree with the concept of having people write small code and do that. In less than 10 minutes I can tell if the person knows basic Java and then get on to the harder parts of the interview including more of soft skills and interests. (I suppose that is equivalent since it is on area?] I view the basic coding question as a screen. if they fail, the interview ends, but success doesn’t mean hire. And I agree on asking open ended/opinion questions. I don’t think anyone hires based on a 90 minute take home test though; I imagine they use that as a screen like i use my < 10 minute question on the phone/collabedit.

DevNexus 2018 – Intermediate Git

Title: Intermmediate git
Speakers: Amanda Olsen

Deck with pictures

For more blog posts, see the DevNexus 2018 live blogging table of contents


Beginner git

  • add
  • commit
  • push
  • fetch – gets latest for other branches (I didn’t know this one)
  • checkout
  • pull

Concepts

  • current branch – the branch you are in when you run a command

Merge

  • git merge feature – merges the code from feature into current branch. All commits since branched in same commit in your branch
  • One cycle of merge conflicts (if merge conflicts)
  • If look at git log, see full chronological history looks as if all changes were made in one branch using original commit numbers.
  • Can see time of initial commit (from history looking like there).
  • Can see time of final commit (from the merge commit)

Rebase

  • git rebase feature – applies the commits one at a time but don’t have merge commits.
  • Potentially many cycles of merge conflicts
  • If look at git log, have new commit hashes for each commit
  • Don’t rebase a shared branch unless you coordinate the effort. If two or more people are developing in same branch, need to be really careful. Merge doesn’t have this problem. If you only have one person in a feature branch, it is a moot point. [at the robotics team, we have multiple people on the same branch; maybe this explains some of our challenges]
  • Rebasing rewrites history in that there are new commits. However, they are the same commits so it is more like a copy. Think of history as parent/child relationships instead. Since you have a new child/new commit, it isn’t really rewriting. Merge has a similar problem. It looks like commits were made in a branch when they were really made in a different branch and “moved” to target branch later.
  • Can see the time of final commit (from the commit)

Merge vs rebase

  • Merge
    • records that it was a merge commit
    • displays chronologically correct history if initial commits
    • Chronologically incorrect history of commits from perspective of master
    • Makes master more complicated
    • Difficult to roll back
    • Creates extra commits
  • Rebase
    • Simple master branch
    • Understanding master is easy
    • Rolling back is easy
    • Master doesn’t record when a branch is merged in
    • Golden rule – don’t rebase when multiple people working on a branch

Feature branch workflow

  • One branch per feature
  • Master is finalized work and intended to be bug free
  • Feature branches probably has bugs and that is fine
  • Very common workflow
  • Other workflows described

Rebasing

  • git rebase –continue – acknowledges that you merged one “group”
  • git rebase –abort – lets you start over

What to do when stuck

  • git reflog – portmanteau for “reference” and “log”
  • Remember that everything is saved if committed it. Local commits like a journal. (but then combine them before push!)
  • Commit any uncommitted changes
  • git reflog to find commit want to go back to
  • git reset –hard – move to that point in time
  • reflog goes back 90 days

Example with squashing commits

  • git clone
  • Create new feature branch
  • Start coding
  • Realize need the code from master
  • git fetch – pul remove branches/origin
  • git rebase -i HEAD-3 – reapplies the last three commits to the tip stepping through each commit. Combines them into one commit with a new commit comment.
  • git pull origin master –rebase – do a pull but rebase (instead of automatically merging). Faster to squash commits before rebase so less to go through when pull.
  • git push origin feature – pushes to the feature branch
  • Then can submit pull request so it gets merged into master

My take

Nice clear methodical explanation. I’m glad she mentioned what was “basic” git since I didn’t know about fetch. I like the recorded “non-live” demos. Great way to save time/reduce risk while still preserving the benefits of a demo.

DevNexus 2018 – Deep Dive into Dockerfiles

Title: Deep Dive into Dockerfiles
Speakers: Raju Gandhi

For more blog posts, see the DevNexus 2018 live blogging table of contents


Benefits

  • read only/immutable
  • unique identifier

What docker files do under the covers

# Start interactive linux container
docker run -it ubuntu:17.10 bash

# create new image (read only file system)
docker commit containerName demo
# list images (local only)
docker images
docker run -it demo bash
# list running images
docker ps

Docker files – like a build file for docker
# base image
FROM ubuntu:17.19
# run command at command line
RUN touch java

Layers

  • each command creates an intermediate image with a new name
  • better to merge commands so less layers ex:
    RUN command a \
    command b
  • But need the code to be readable
  • same idea as git commits – a tree where points to parent and knows the diff
  • each OS has limit of number of layers. On Mac, this is 127
  • if run apt-get install and then apt-get clean-all, you’ve increased the image size. Two layers, one to add and one to delete. Want both in same step so doesn’t increase size by whole file size twice!.

Cache

  • every Docker pull leverages the cache
  • RUN touch java and RUN touch    java have different sha hashes and are considered different commands. So cache not used
  • Do not write RUN ls -l or other commands for debugging. You can just open an interactive bash into that layer to debug
  • Put commands that move files towards the bottom. This allows for more reuse of the common parts of the image.

General notes

Don’t install sshd. Can use docker commands for that.

Dockerfile

  • FROM
    • Implies “ancestry” – what is parent image and what will you be inheriting. Ex: running whoami when inheriting jenkins image, it prints “jenkins”. This means you have to look at lineage if having permission issues. May have to keep looking at parent and grandparent and …
    • Must be first line
    • Consider starting with Ubuntu and building yourself so know what is in there. Less security implications if do it yourself.
    • Rare, but can write “FROM scratch” to start over. Usually only used for go code.
    • While multiple FROMs are allowed, it is a terrible idea. Diamond problem; they can conflict on basic things like version of Ubuntu.
    • Do not use “latest” tag. Use an exact tag. “LATEST” is a lie. It is just a tag. You can tag versions after LATEST. If you don’t switch the tag, it is still the old one.
    • Inspect ancestors for USER, PORT, ENV, VOLUME, LABEL, etc
    • docker inspect – lets you see what is in there. Recommends tracing by hand to be more thorough.
  • RUN
    • Don’t run commands that upgrade the OS. Use a later base image instead.
    • Group commands with && so not adding more layers
    • Beware of cache. If write RUN apt-get update, it will cache the result and not run again. If use && for all related commands, they are unique.
    • Want each command on separate line starting with && and ending with \ (except first and last). This makes it easy to git diff to see what changed
  • ADD/COPY
    • Combine COPY and RUN
    • Much of RUN applies
  • LABELS
    • Use lots
    • Labels can read ENV variables
    • Can use image (compile) or container (run) scope
    • Ex: build number, scm location
    • Just like RUN, can merge all LABELS in one line. Just end line with \ to continue (no && like when running)
    • To read label, do docker inspect and “grep Labels”
  • ENTRYPOINT/CMD
    • Both can run commands
    • Both can take command raw (xxx abc) or as array of command/args ([“xxx”, “abc”]). Better to use array so bash doesn’t have to fork
    • Run [“/bin/bash” “-c” “xxx” “$arg”] if need variable expansion to get bash involved
    • Better to have a shell script and call it with ENTRYPOINT. That way gets treated as a shell script without having to call bash. It is also easier to read since you aren’t writing bash as strings. The cost is that you add a layer because you have to copy the script into the image.
    • docker stop id – takes 10 seconds because need to send a signal to PID 1 and have it stop

Other practices

  • Create you own ancestry/hierarchy.
  • Containers are changing how we ship software. Don’t put Oracle’s JDK in an image and then put on dockerhub. Legal issues.
  • Consider using multi-stage builds.
    • FROM x as y …. FROM z – different scopes – binary executable vs build tools.
    • “as y” is what makes it a multi-stage build. Everything until the next “FROM” is not part of the container. The “FROM” without an “as” creates what will go in the container.
    • Only contains what need. Not the build tools. Smaller image. Less “extra” stuff.

My take

This was really good. It was clear if you didn’t know much about Docker while still having good info for those somewhat familiar. For the best practices, some people were taking notes on what to fix! I actually realized that I applied one of his anti-patterns to a Java compare program I wrote. I need to go and add some new lines in my generator for ease of diff! More gray/black background for code though. Blue (comments) on a dark background is hard to read.

Also, it is great that DevNexus has tables in the first few rows. Reward for sitting up front! (I chose to blog on my Mac as I expected to type a lot of commands).