Sunday, December 02, 2012

Some people don't customize emacs. If you are one of them, there's no need to read further. However, the more packages you use, and the more you want to optimize, the more customization you require. Furthermore, the more customization you need, the more valuable that customization is, and the more you want to keep it around. With Emacs 24 and ELPA, getting and using packages is incredibly easy, so I anticipate that customization is going to be more important than ever.

I'm planning to write a series of posts on customizing Emacs, sharing tips and developing elisp to make the job easier. This is an introductory post to this series.

My first tip is to store your setup on github. I've done this with my emacs-setup project. I'll be updating this repository as I develop new elisp. Having your setup on github means you can put it on any computer you use, and other people can see and refer to your config. Stealing bits of elisp from other people's setup is a long-held emacs tradition, and github makes this easy.

My second tip is to store your configuration in ~/.emacs.d/init.el, not ~/.emacs. The .emacs.d directory is where all the action happens these days. Configuration files are stored there, as well as ELPA packages (in the elpa subdirectory). So if you are just starting your configuration, put it in ~/.emacs.d/init.el, or else move your existing configuration there.

Finally, all the tips I'll be giving assume Emacs 24. If you haven't upgrade, please consider doing so.

Stay tuned for more tips!

ELPA for App Engine

I've just released on open-source project: ELPA on AppEngine.  This is an implementation of ELPA written in the Go programming language, that runs on AppEngine.  Right now it isn't ready to be a real running system, but it probably won't take too much work to get it the rest of the way there.

It might have the possibility into being a really cool ELPA that is open to all, as opposed to the other ELPAs which are hand-curated.  I'm still thinking about where I want to take this.

Thursday, March 15, 2012

Tips for code interviews

If you are a programmer, then you inevitably spend some time every few years doing a bunch of interviews for a programming job. You probably are going to have to do some code interviews as part of that, which means you'll be doing coding interviews many times throughout your career.  Allow me to help.

Since I previously wrote a post on why I prefer coding interviews, I thought I'd follow up with some tips for doing well at these things.  I suppose it can also double as a list of things to look out for if you do code interviews.

The problem is, coding interviews, done well, are a pretty accurate gauge on your ability to code.  If your coding is rusty, it's hard for that not to show up during an interview. Still, there's a few things you do to help your chances.

  • If you are given a choice in languages, choose the most high-level language you are relatively good at.  So if you code mostly in C++ and sometimes in Python, use Python.  The coding will be faster and easier. If you aren't a regular user of any high-level language, though, better stick with what you know.
  • Know your chosen language well.  Know the standard data structures - sets / hashtables / lists / arrays.  If it's C++ or Java, know how to use Generics.  Know the features of the latest version.  If you tell me you primarily program in Java, but haven't used any version over Java 1.4, I'll feel you just don't care very much about programming.  On the other hand, if you tell me about upcoming features in C++11, I'll be pretty impressed.
  • Know when to use each type of data structure.  In Java, if you don't care about ordering, and items shouldn't have duplicates, don't use a List. Use a Set.  I am supremely annoyed when candidates just use LinkedLists for everything.  In fact, using it for anything is usually a bad sign.  Make sure you understand why.
  • You don't have to necessarily complete the whole program in order.  Feel free to write the main structure of the code, then fill in the more complicated bits later.
  • Go back and refactor code if possible.  Don't leave your code in a messy state if you think you have time to fix it.
  • Test out your code on an example.  I can't stress enough how important this is.
  • Choose meaningful variable names.  Not just good practice stylistically, but you are less likely to trip yourself up.
  • If the algorithm you are coding could be done in several different ways, choose the easiest way to code up first.  Then if you have time you can change it or just explain to the interviewer how to improve it.  It's better to have complete suboptimal code than incomplete optimal code.
  • Make sure you can figure out the running time of simple programs.
  • When physically writing on a whiteboard, leave as much space as possible between consecutive lines.  You often will have to go back and insert things in between lines.  Having to erase or write somewhere else and have an arrow pointing to the insert point will make things look confusing, which is bad for your comprehension.
Now, if you feel you are rusty or just a bit slow at coding, these tips won't help you too much if you can't actually code up the problem in question in time.  What you can do, though, is train this skill by doing coding exercises.  There's a few sites that offer small coding exercises, such as CodeSprint or  Project Euler.  Do these as much as possible before your interviews.  Don't just wait until you are actually about to interview.  Start as soon as possible.  

If you have any other suggestions for doing well in coding interviews, please share in the comments!

Sunday, March 11, 2012

The code interview

I was halfway through the bad interview when I realized that my method of interviewing was fatally flawed.  The candidate I was interviewing just did not make the conceptual leap to come up a way to solve the problem, no matter how many hints I gave.  The problem, which I don't wish to reveal, wasn't a classic a-ha type puzzle type problem, like the three lightbulbs controlled with two switches, but it was a software engineering problem that required some insight.

What worried me was that some candidates got the answer to my question instantaneously.  Almost no thought needed.  Oh, so you want to accomplish X?  How about a scheme that does Y?  Other candidates needed to think about it for some time.  But this one didn't get it even after about 15 minutes.  Are the ones that get it instantaneously really so dramatically better?  I knew from experience that many who came up with the answer fast didn't do well on the next part of the question, or overall in the rest of their interviews.

As the interviewee continued to metaphorically bang his head on the wall of the question, I realized that this part of the question was meaningless. I couldn't say for sure that a great performance on it would indicate a great engineer, or a poor performance would indicate a poor engineer.  Worse, my candidate had to struggle without making progress for quite a while.  He wasn't feeling good about it.

I was ultimately wasting time.  15 minutes spent determining that the interviewee can't answer a specific issue is 15 minutes that only yields a small amount of information.  Either the interviewer realized the answer or not, so I really only got that binary signal.  

At that time I had another question in my repertoire, which was a simple coding exercise, significantly more complicated the FizzBuzz, but less complicated than writing merge sort.  Pretty much the exact opposite of this type of question.  Anyone that can write code could do it.  But it turned out that performance on it was still variable, which was good, and I never got the feeling that performance was random.  Also, I was able to get all sort of signals: how fast the candidate wrote their code, if they remembered details about their language, if they made mistakes, if they remembered to test their code, etc.

After this bad interview, I switched almost exclusively to this simple coding exercise.  After I made the switch, I never had a bad interview again.  Candidates always made progress on this question.  They almost always finished the implementation.  They may have had to think about some parts, but they always left thinking they did a reasonable job.  And I never had to sit through and puzzle out how to drop hints to solve some algorithmic problem that the candidate is just not grasping.

With everyone pretty much able to finish the question, I judge candidates on the following:
  • How quickly were they able to finish the code?  
  • How correct is the code? 
  • After writing the code, did they go through the code to test it against some sample data?
  • How familiar do they seem to be with the language they are writing in?
  • How elegant is the code?
  • Is the code efficient?
Additionally, I'd ask a algorithmic question or two after this, if we have time, to see how they can speed up the code.

Usually, the answers to these are pretty well correlated.  If you can code elegantly, then you can usually code quickly, which them means you will have time to test and correct the code.  At the end, I think I have a good judgement of how decent a coder the person is.  If the candidate is a good coder, I almost always recommend hiring.

If you are thinking of asking a coding question, here are my recommendations, based on an interview time of 45 minutes:
  • Make sure you can write the code from scratch in about 15 minutes.  That doesn't sound like a lot of time, but you already know how to solve it, presumably, or else you wouldn't be asking the question.  All candidates, good or bad, take longer than you may think to code something up.
  • Have follow up questions that are algorithmic in nature.  What is the running time of the code?  How you can make it faster?  Could you parallelize it?  This is all for when the coding is finished.  If the coding never finishes, don't ask these questions.
  • Insist on real code, not psuedocode.  Let the candidate choose the language they are most comfortable in.
  • If you don't have a good coding question, look at the last few bugs you fixed.  Could one of them be an algorithm that could be simplified and turned into a coding exercise?  The existence of a bug is proof that the algorithm isn't too simple.
Judging a candidate can't be done through coding questions alone.  Algorithmic and design questions are necessary too.  But I'd ask coding questions first, since they seem to offer the most solid and reliable feedback.

Saturday, February 18, 2012

Work / life balance advice

Don't let either your personal life or your work life go neglected.


There. That's it. If you are short on time, you can stop reading now, since that's the one most important thing about work / life balance.


Oh, you're still here? I might as well talk about the actual balance part, then. The part before was just about boundaries, but within those boundaries are many possibile ways to allocate your time. I'll try to keep this advice short too: Do you what love, be flexible, and keep learning.


"Do what you love" is pretty standard advice, but most people use it to talk about your career. It applies to your extracurriculur activies too. It means that your time on nights and weekends is best spent pursuing the priorities that are important to you at the moment. For an engineer right out of college, that probably is some combination of working and hobbies. For an engineer with a family, that is mostly going to be family activities and hobbies. That might be family activities and work, but family activities, at least with young children, are a fair bit of effort. I think hobbies balance out better with family life.

Lets assume that you have a family, since that is when people start thinking about the work / life dilemma. I think it is completely reasonable to work just 40 hours a week. However, you have to make sure that those 40 hours are spent wisely. No wasting time at work. In fact, you have to make you are always working on the highest priority task, keeping your focus, and not going to unimportant meetings. If you do those things, you should do well even if others are working 12 hour days.


"Be flexible" is just saying that you shouldn't have any hard rules about work / life balance. Sometimes you do need to take extra time for work, to fight some emergency or to finish off a release. Or sometimes you need to take less time than normal for work, so you can tend to issues that come up at home. If you have an urgent family situation, your work should be flexible and let you take time off. And if you have an urgent work situation, you family or other non-work life should be flexible and allow you to work that extra time. So what I said before about not letting work or personal life go neglected is not necessarily true for short periods of time. It's only true for the long run.

"Keep learning" is about the reality that there is a bit more you need to do away from the office. You need to work to keep your skills fresh. That means not only devoting time to learn new technologies, but also reviewing the fundamentals. The good news is that this doesn't take a lot of effort. I'd guess an hour a week of study or experimentation is sufficient. More is better, of course.

I've seen too many people, both old and young, stagnate because they only did their work. It isn't enough, because change is constant in this industry, and fundamentals are easy to forget. It is good if you can respond to changing technologies, but even better if you can lead some of that change. Keeping your fundaments sharp and keeping up with new technologies will put you in a good position to do either.


Finally, I'll leave you with a piece of concrete advice: Don't check email within three hours of your bedtime. It raises stress levels, and on receiving mail, you are often compelled to act on them or reply to them. Even if you choose to be working in the evening, just work, and skip the email.

Saturday, October 08, 2011

code-imports

I finally put up the emacs based code import-management solution I've been using for a while. I wrote a similar thing a few years ago at Google, but I rethought and rewrote this, plus added a bunch of ert tests. I've put it up as code-imports in github.  The module allows you to organize imports according to predefined rules, as well as grab other files as imports and add them as imports to a target file.

As opposed to the earlier incarnation, I've extracted as much as the logic as possible into purely functional functions, which makes it easy to test.  In my experience, import management is complicated enough that manual testing is just not enough to ensure a stable product.  Testing the code thoroughly is one way to solve this problem.  I've also simplified the number of concepts in the code, and the number of variable to tweak to the bare minimum.

I'm going to refine this a bit, then announce it more broadly shortly.

Saturday, April 09, 2011

A brief demonstration of emacs new lexical bindings

It wasn't a joke.  On April 1st, Stefan Monnier merged the lexical binding branch into the emacs trunk.  Unless it needs to be rolled back, emacs 24 should have lexical binding, which is a huge improvement for elisp.  If you want to try it out, get the latest emacs from source, and compile it yourself.

To enable it, you need to set lexical-binding to t.  This is buffer local, so you need to set it for every buffer that you want to have lexical binding in.

Here's a demonstration in an ielm session (M-x ielm).
ELISP> (setq lexical-binding t)
t
ELISP> (defun make-adder (base) (lambda (num) (+ num base)))
make-adder
ELISP> (setq x 1)
1
ELISP> (setq 1-adder (make-adder x))
(closure
((base . 1)
t)
(num)
(+ num base))
ELISP> (funcall 1-adder 10)
11
ELISP> (funcall 1-adder 100)
101
ELISP> (setq x 100)
100
ELISP> (funcall 1-adder 100)
101
Without lexical binding, the variable x would be a dynamic variable, and so when we set it to 100 later in the session, the 1-adder would change to a 100-adder inadvertently.  In fact, if we try, we can't even get to that point.  Here's the same session without lexical binding:
ELISP> lexical-binding
nil
ELISP> (defun make-adder (base) (lambda (num) (+ num base)))
make-adder
ELISP> (setq x 1)
1
ELISP> (setq 1-adder (make-adder x))
(lambda
(num)
(+ num base))
ELISP> (funcall 1-adder 10)
*** Eval error *** Symbol's value as variable is void: base
What's going on here?  Notice that when we make the 1-adder without lexical binding, we don't get a closure.   Instead, we just get a function that references num and base.  num is passed into the function, but base is a dynamic variable, so it is interpreted in the emacs global context, as opposed to a context inside a closure.  The variable base is not bound to a value in the global context, and when we execute the lambda, which refers to base, emacs looks for the base variable, cannot find it, and throws an error.

This doesn't happen with lexical binding.  In that case, we can actually see the closure itself being returned when there is lexical binding:
(closure
((base . 1)
t)
(num)
(+ num base))
The closure here shows a structure in which we can interpret to mean that base is being bound to 1.  You can also see num is the argument (since it is not in the same s-expression as the binding of base), and then it proceeds with the simple addition function.

I haven't yet made use of closures in my emacs code.  I don't really need it in my initialization files, and if I writes modules that assume it then almost no one can yet use it.  So I'll give it time, but it's a huge step in making elisp a better lisp.  Read more about lexical bindings Paul Graham's wonderful free book On Lisp.

Lexical bindings are not only a good feature in themselves, they are also is an important step on the way to multithreading.  Having nothing but global variables makes threading quite challenging, and lexical bindings in the standard elisp packages can help make multithreading easier.