At Khan Academy, code review is a key step in our engineering workflow—we use it as a mechanism for quality control, context sharing, and more. (See: Code reviews at Khan Academy.)
In making the jump from university (I graduated in June) to Real Engineering™, code review was one of my weak points. I hardly knew anything about it. At school, you never review code. On the job, you're reviewing daily.
With five months of consistent reviewing under my belt, I've begun to notice that where I read code influences the types of observations I can and am compelled to make.
Robolectric is a useful tool for testing code that touches parts of the Android SDK without building to a device, made possible by Robolectric's reimplementation and "de-fanging" of parts of the Android SDK, which allows them to run on a regular JVM, rather than an emulator.
I recently integrated Robolectric into our app at Khan Academy—we've been looking into ways to let us write more and more efficient tests, and Robolectric fit the bill nicely (at least for some cases—many tests are best left as functional or integration tests; but I won't get into that here).
Setup was relatively painless, but I did hit a few snags along the way. In this post, I'll outline those snags—and how we got around them—to save you time and effort in your own Robolectric integration battle.
I'd never touched Android before, but I was pleasantly surprised to see that email, since the vision of bringing Khan Academy to Android devices had intrigued me for a while. If you imagine a world in which every student, everywhere has access to a free, world-class tutor in their pocket, Android is a big part of it. Joining the team struck me as a fantastic opportunity for impact.
So, I conveyed my excitement to Ben; but I couldn't help but ask:
Is it an issue that I have no experience developing on Android?
In his response, Ben explained that this move would be part of a long-term effort to scale up Khan Academy's Android expertise. And that it was expected that there'd be a significant learning curve to getting me up and running on the platform.
Three months later, and I've built out new features, fixed nasty bugs, and grown to the point where I can meaningfully contribute to our team's technical discussions, as an Android voice. All having started from scratch in mid-September.
It's a wonderfully weird feeling.
This semester, I've been taking a course on Bitcoin and Cryptocurrencies, offered by Princeton's Center for Information Technology Policy, and co-taught by Arvind Narayanan and Joseph Bonneau (with help from Ed Felten and Andrew Miller).
Avik promised that Flow would be open-sourced by the end of the year and, true to his word, the project appeared on GitHub a few months later.
At Khan Academy, we put a lot of effort into creating interactive math content (e.g., Drawing Polygons).
The kinds of interactions we focus on are particularly important on touch devices: to create an engaging mobile experience, we strive to provide interactive content that feels effortless and fun—tightening the feedback loop as much as possible and enforcing the illusion of complete control.
Poor performance kills this illusion: if a user drags his or her finger across the screen and the polygon lags behind noticeably, the shapes feel heavy and the interaction becomes a chore.
So, when we recently discovered that many of our interactive exercises run at rates as low as 12 FPS on tablets, it was pretty startling.
I love working with React. Like, a little too much (no thanks to my (amazing) internship at Khan Academy, where we use React in buckets).
For a recent side project, I wanted to render my React components on the server, rather than the client (this is often abbreviated as "server-side rendering", or SSR, for short).
Typical motivations for rendering on the server include:
(This isn't to say that SSR is strictly better than client-side rendering; it's just different.)
SSR is totally doable with React; but a lot of the SSR-related resources out there seem to assume prior knowledge. I thought I'd share what I've learned.
Thus marks the end of the Third Annual "Healthy Hackathon", Khan Academy's weekend-long celebration, which featured awesome improvements to our CS platform, awesome (and hilarious) fundraising efforts, and awesome (and hilarious) music videos, to name but a few of the fantastic hacks.
I just finished Bill Simmons's absolute masterpiece and basketball Bible aptly titled The Book of Basketball (TBOB).
His thesis revolves around The Secret: that is, that the key to basketball isn't about basketball. The truly great teams in NBA history didn't win based on talent (alone). Instead:
... they won because they liked each other knew their roles, ignored statistics and valued winning over everything else. They won because their best players sacrificed to make everyone else happy. They won as long as everyone remained on the same page. By that same token, they lost if any of those three factors weren’t in place.
That said, what really got me thinking in TBOB was the role of statistics in basketball.
Last Spring, I did a semester of independent work (IW) with professor David Walker. My project was focused on rule optimization in Software-Defined Networks (more here), and it was probably the greatest learning experience of my Princeton career (so far).
I worked hard, and I learned a ton—not just about SDNs, but about the research process in general.
Every COS major will do IW at some point. The COS Department has a decent guide here, but after comparing and contrasting my experience with those of my friends, I wanted to jot down some notes about what worked and what didn't.
My goal was to automate the process using a headless browser (that is, a browser that runs without a GUI, allowing you to navigate the web and interact with web pages from your terminal). In this case, I chose to use PhantomJS.
I had a mixed experience. Headless browsing is notoriously difficult to debug, and this case was no different: errors were tough to reproduce, results were inconsistent, and producing informative output was challenging.
Once I got past the initial difficulties, however, PhantomJS was an impressive tool—hats off to the creators, as always.
In this post, I'd like to describe some of the common "gotchas" that I've found associated with PhantomJS and walk through their solutions. (I call them "common" due to: 1. my own experience, and 2. finding similar questions/issues documented on StackOverflow.)
Update: Quizzler was built as my entry into the Facebook Summer of Hack Hackathon in August 2013 and was selected as the winning hack. Thanks to Facebook for hosting a great event.
After playing a number of poorly-made iPhone quiz games, I decided to roll my own. But I didn't want to spend time creating my own corpus of questions. Thus, Quizzler was born, an attempt to build an iPhone quiz app that generates its own questions.
I like SSHing into things. So I went ahead and setup my own AWS EC2 instance. Under the free tier, you can get good mileage out of an instance and use it to do whatever you please.
But it took me awhile to get the thing up and running properly. Here are the things I wanted to have:
If that experience sounds good to you, keep reading. I've pulled together the assorted posts that I used to setup my EC2 instance and assembled The Idiot-Proof Guide.
Motivation: There's a lot of information on Wikipedia, and people want to use it. Sometimes, these people are programmers; and sometimes, their customers aren't computers.
I needed to parse some information from Wikipedia programatically and present it in a human-readable format, i.e., for clients. I found that a bunch of other people had similar issues (e.g., here and here), so I've open-sourced my solution.
Last fall, I began exploring the subject of functional programming as part of Professor David Walker’s COS 326 at Princeton. Throughout the course, we did all of our programing in OCaml. I also spent the past spring using OCaml for my CS Independent Work. So in total, I’ve spent a reasonable amount of time around the language, and I think it’s fantastic: it’s got a great module system, plenty of useful open source tools, etc.
But OCaml isn’t that widely used. And as a result, there aren’t very many good write-ups out there for setting up an OCaml development environment.
In this post, I’ll provide a couple of choices for setting up such an environment when developing on a Mac.
I'm doing some independent work this semester with Professor David Walker, with whom I took functional programming last semester. My project is being implemented functionally, however the main focus is on rule optimization in network routers; specifically, routers within software-defined networks (SDNs).
OCaml provides a nice library for multi-threading. Problem is, according to my professor, under the hood, OCaml doesn't actually employ any parallelism at all! In truth, the compiler just interleaves instructions in a way that has the same computational effect as multi-threading, barring the 2x speed-up.
On the side, I've been working on an alternative to the small Futures module we used in class. Futures are very similar to threads but safer and easier to use. The interface itself is composed of a create method, which takes as argument an expression to compute and performs said computation on a new thread; as well as a force method, which blocks the main thread until the Future has finished its computation.
I was recently introduced to lazy computation in the context of streams—very cool (and powerful) stuff. In this post, I’ll go through streams first, then use lazy computation to address a problem specific to the data type before closing with an example.
I spent some time yesterday fixing some performance issues related to EveryCollegeCal (my iOS app). Basically, I was seeing very slow, choppy segues between the first two views (one of which is a welcome screen, the other a table view). On top of that, the scrolling performance of the latter view was equally gross.
In the end, the fixes were not too involved—i.e., they didn’t involve a spectacular amount of code (of course, this can’t be said of all performance issues, so I count myself lucky). And there were only two necessary changes: the choppy segues were fixed by swapping out my glossy button library, which was apparently very inefficient. But the second change demonstrates something cool about iOS performance tweaks: while they’re often subtle, the under-the-hood explanations are always logical.
N.B.: I wrote this post a few weeks after first using OCaml. Before that, 90% of my programing had been in Java. Looking back on these notes, perhaps a more accurate title would be "First Thoughts on a Functional Language After Only Knowing OOP", or something along those lines. But for posterity, I'll leave it as-is.
I’ve been learning to program in OCaml for one of my courses this semester (COS 326: Functional Programming) and I can't remember the last time I was this excited about anything CS-related. Learning to program functionally is like learning to program all over again.