The first day was no disappointment. In fact my classmates were impressive enough that I felt just a bit of impostor syndrome. One thing that makes it especially interesting is that half the students in the school were just starting as I was, and half the students are in a cohort that is about half way through the program. That other cohort was shockingly capable! One of the first things we did was pair off with advanced students so they could demo their projects to us.

(more…)

Since my arrival in San Francisco last summer, I've become aware of the new "hacker schools" popping up around the city. Their stated purpose is to take smart, motivated people who may or may not have a strong technical background and turn them into world-class junior developers in a short time.

The Starter League

The first school of this type that I ever heard of was Code Academy in Chicago (renamed as The Starter League due to name confusion after the online school Codecademy launched). Their system was pretty unique-- students spend 8 to 10 hours per day for 2 months, working in pairs as they learn a stunning amount of ruby, HTML/CSS/JS and Ruby on Rails. At the end of this time, they have an interview day in which they demo their projects to various tech companies, including some of the hottest local startups. The school has only been running since 2011, but results have been excellent and even DHH, the creator of Ruby on Rails, is a fan of the program.

SF Hacker Schools

With that kind of success, it wasn't long before similar schools started popping up in the Bay Area. The demand for top notch developers is extreme here, but very few companies are willing to train and they take only a tiny fraction of their applicants. A program to quickly bring students up to speed in the technologies that local start-ups are using is the perfect solution. It's an incredible learning experience for the students that opens doors, the companies can hire solid programmers to join their teams and schools can earn money from either or both of the former two groups. From what I understand, Dev Bootcamp's first class was hugely successful--Over 90 percent of the students landed jobs shortly after graduation (at nearly double the average US salary) and of those who didn't one opened a similar school called App Academy that focused on iOS development and the other opened Hack Reactor, an even more intense school with a stronger focus on JavaScript and front-end technologies. There is also another school, which I know less about since it doesn't accept men.

In contrast with computer science degrees at universities, these schools have less of a focus on CS theory and more of a focus on building things. Students write a lot of code, and they use newer languages and frameworks. Another feature is heavy use of cutting edge tools and various automated testing frameworks that are commonly used in bay area start-ups, but not so common yet at larger, more traditional companies. Most striking to me is the intense nature of the study. No college I've ever seen puts students through 8 class hours of computing classes per day.

The bay area hacker schools remind me more of high-end intense language schools! There are a number of 6 hour per day intense language learning programs in which students work in pairs or small groups, work hard, and acquire a great deal of vocabulary, speaking skills and reading skills in a short time. In my experience learning mathematics as a teenager and then later learning Japanese and Chinese in my 20s, working at something 4 hours a day isn't just 4 times as good as 1 hour a day. It's probably closer to 10 times as good. So even before encountering any students of such programs, I was bullish about the idea. But when I did finally some students from App Academy and saw how much they had picked up in only a month of classes, I knew I had to join.

My quest to get in

They had only been in class for a month or so, and their class was free since they were the inaugural (i.e. guinea pig) class. In that short time, they had already picked up enough to start making some kind of fun iOS projects! Beyond that, I hung out with a bunch of them and played a cool board game called 7 Wonders or something like that. It was a fun group and they were genuinely excited about what they were learning. I had some background in iOS. Not fully aware of how rigid the program was, I bought a Macbook and started working on the materials they were using hoping I could get into the program in some way. I realized pretty quickly it wouldn't be possible, so I didn't press the issue. But I did ask the instructor what other materials they used and I applied for their next batch, which they said would be focused on web development with rails and importantly would only charge tuition for students successfully hired.

Next, I started learning all I could about similar programs, what it would take to get into them and how expensive they were. Unfortunately, for the most part, they're pretty expensive. Dev Bootcamp, for example, costs 12k. That's more than I spent on tuition for all of my B.A. at one of the better public universities! They're flooded with applicants and pretty difficult to get into, also.

When it came time for winter applications, I applied to multiple schools. I talked with former students to get as much of an idea what they were looking for. One of my major difficulties since coming back to the US has been much of what I accomplished in Asia (language learning, running a business in a foreign country, etc...) doesn't really translate into much social proof here. It's awesome for social settings, but in interviews or people evaluating my professional abilities, my background looks a bit meandering. So, I focused on my track record of learning hard things, my adaptability and my genuine interest in education. I think it went fairly well. I made it to the interview stage with 100% of my applications in which I followed this strategy.

Interviews

Hack Reactor had a pretty extensive process. Of all the schools I applied to they were the only one to require a video. They asked me to teach something I was interested in. What a perfect thing for me! I put my heart and soul into teaching for most of my 20s! The challenge was not to teach something I wasn't so interested in anymore, such as Chinese learning or something that would likely be boring to them, such as phonics. In the end, I decided to explain what spaced repetition systems are and their strengths and weaknesses. After that, there was a general interview. Last was the technical interview, which was kind of hard. It was an interesting system, though. The interviewer actually taught me some useful things about prototypical inheritance in it, and I had them down pretty solidly by the end. I felt good about my showing, but they clearly had a high bar technically. Still, even if I got a rejection letter the next day, I had learned how to monkey patch Javascript classes!

The technical interview with App Academy on the other hand, was terrifying. I knew they were the only program I could afford, and my hopes were pinned on it. I started out pretty confident, but then the interviewer asked me the scariest possible question-- Fizzbuzz! Before he'd even finished explaining it, I felt my heart sink. Knowing how ridiculously high their applicant to student ratio was, with a question that easy I'd probably have to solve it as quickly as I could type. Who knows what else I'd be filtered on... language choice? Running correctly the first time? I decided to use ruby since that's what they use, and typed as quickly as I could, made a few errors, corrected them and ran my program through a fizzbuzz grader I just happened to have made a year earlier to ensure it was correct. For a moment the instructor thought I'd made an ordering mistake with the mod 3, mod 5 and mod 15 conditionals but then realized all was good and said as much, sounding pretty upbeat. What a relief! The rest of the interview was mostly questions about why I was interested, whether I'd be able to devote my full attention to the program, etc. I asked a few questions of my own and all seemed to go well.

Disappointment

But I didn't get in. That was rough. After having sought them out last summer, talking to the students of the first batch and clearly being so motivated it was a blow to get rejected. Worse yet, when I emailed back to see what I should work on to be a stronger candidate for their next batch, they told me I was out for six months. For someone in my financial/career state, six months was dream killing. All over a stupid fizzbuzz interview! Still, I have to say that Ned and Kush were incredibly kind, far beyond the call of duty. They gave me a good amount of feedback, and were helpful in a number of ways. I'm sure they were flooded with applicants, too. Ned even went so far as to offer to intro me to other schools whose owners or instructors he knew. Unfortunately, all of them had 10k+ tuition fees taken up front instead of after job placement like App Academy's system.

Around that time I heard back from Hack Reactor, asking how much financial aid I would need to do their course. The amount I told them was pretty much undoable. Still, though... it made me wonder. If they were contacting me again and they already knew my situation from the previous interviews, maybe there was still a shot. It was an exhilarating feeling! Of all the schools I'd visited, Hack Reactor seemed to have the highest bar in terms of everything. Other schools went five days a week, they did six. Other schools had nine hour days, they had eleven hour days. Other schools went for two months, they went for three. Also, their focus on JavaScript frameworks was a plus to me. Studying at a school with such a tough entrance filter would not only give me skills that would greatly improve my ability to do more interesting tech work in Silicon Valley, but it would also impart much needed social proof to convince various gatekeepers to give me opportunities. It was time for extreme measures.

Tenacity

I went out every bank I could find in the city. I knew a loan wouldn't be easy since banks are big, slow-moving, conservative behemoths that would almost certainly have no loans for non-university schools that have only existed since 2011. The fact that I have essentially no US credit history for the last 10 years didn't make things any easier. I channeled everything I've learned about sales from my entrepreneurial experiences going back to the house-painting franchise I ran when I was 20. I found bankers who had heard of the new hacker schools and showed them statistics on previous graduation classes on my Macbook. They said no. It sucked, but I kept looking for more creative ways of funding the class I scraped together just enough. And I got in.

It was a thrilling moment. It's a little terrifying as well. This is my shot. It took a lot of tenacity to get it. I have 12 weeks to make the most of it, and it starts tomorrow.


I'll probably be way too busy to write in detail, but I'll be keeping a log of notes, study tactics and observations here. Expect to see projects showcased here as well.

During my recent project working on the redesign of Spencer Day's promotional site, I encountered a maddening cross-browser quirk. A critical component of online marketing is email newsletters, and part of the site redesign was heavily customized sign-up form. After some work, I had a pretty nice looking form that appeared nearly identical in Firefox, Chrome and IE:

ff-form

Safari, on the other hand looked TERRIBLE:

safari-form-bad

It was generated by the following CSS:

/* Mailing list form */
#mc_embed_signup {
     position: relative;
     height: 32px;
}

#mc_embed_signup form label {
     background: none repeat scroll 0% 0% rgba(0, 0, 0, 0.7);
     border-radius: 5px 0px 0px 5px;
     color: silver;
     position: absolute;
     left: 0px;
     top: 0px;
     width: 185px;
     height: 29px;
     padding-left: 10px;
     padding-top: 0px;
     padding-bottom: 0px;
     vertical-align: 10%;
     font-size: 15px;
     line-height: 29px;
     font-weight: bold;
}

#mc_embed_signup form input#mce-EMAIL {
     position: absolute;
     top: 0px;
     width: 285px;
     height: 28px;
     left: 195px;
     padding-left: 5px;
     padding-bottom: 0px;
     padding-top: 0px;
     font-size: 15px;
     border:0px;
}

form input.button {
     color: #555;
     position: absolute;
     right: 67px;
     top: 0px;
     height: 28px;
     padding-top: 0px;
     padding-bottom: 0px;
     font-size: 15px;
}

It's always frustrating when one Webkit browser (Safari) doesn't even look like another Webkit browser (Chrome). In this case it's clear that Safari ignores the styling provided in form input.button part of the CSS. It took some serious searching to figure out why, but I did. Apple doesn't allow the styling of "native" buttons. To get a button to be accepted as "non-native", you can add a background color (even the same color currently in use).

form input.button {
     background: #ccc; /*without this, safari ignores styling*/
     color: #555;
     position: absolute;
     right: 67px;
     top: 0px;
     height: 28px;
     padding-top: 0px;
     padding-bottom: 0px;
     font-size: 15px;
}

Now the signup form is roughly* the same across all major browsers:

ff-form

safari-form-good

*sloppy screen-shot snipping aside

I've been using VirtualBox pretty happily for the past couple of months on my commodity Windows laptop, but recently made a pretty unpleasant discovery. The install wizard had some poor wording in regards to setting up hard drives. They encourage a very small drive (8gb on my machine), and the installer says that it's dynamic. Unfortunately this doesn't mean that the drive grows as needed. It got to where I couldn't pull from the git repo I was working on.

After much frustration, I managed to increase the size of my guest Ubuntu VBox drive. This is what I did. (If you have saved snapshots of your partition see this before continuing!)

On the Windows host system, find the VBoxManage.exe file and the .vdi file that is your virtual linux HD. Run VBoxManage with the following params: modifyhd (path_to_your.vdi) --resize (size in MB).

This is what my command looked like:

c:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd "C:\Users\LMason\VirtualBox VMs\ubuntu\ubuntu.vdi" --resize 32768

After this, I could see from looking at the VirtualBox window, the HD was properly set to 32GB:

To the best of my knowledge, Ubuntu lacks a built in tool to resize its partitions. For this, I downloaded the latest ISO of GParted, then shut down my Ubuntu machine went into its Vbox Settings->Storage, added an IDE controller and loaded it with the gparted-live.iso, and checked the live CD/DVD box.

Then I restarted the Ubuntu box and it booted to GParted. I saw a display with my main partition on the left, my swap partition next to it, and a huge unpartitioned block to the right. At first, it still wasn't clear how to increase the size of either partition. When I selected a partition and clicked resize, the increase arrows were grayed out and I could only decrease the size of the partitions. After a while, I discovered that in GParted, a light blue border around a partition means that it can't be moved and that no other partition next to it may grow in its direction.

The key is to delete the swap partition first. After that, I was able to move it's container to the far right end of the unpartitioned area, set the size I wanted for it and then create a swap partition inside it. Then with nothing next to the main partition, it was able to grow to take up the full space available.

This is a collection of my notes on Code School’s, Realtime Web with Node.js course. It follows the first set of notes on setting up a node server, using curl, read streams and write streams (levels 1-3), and the second set on using NPM, putting your dependencies in package.json and setting up the Express framework (levels 4-5).

Level 6

Socket.io allows you to create duplexed websocket connections in your node.js application. This allows data to be sent from client to server, from server to client or both simultaneously.

Setup

After installing socket.io with NPM, you need to require it on the server side.

// in your app.js
var socket = require('socket.io');
var app = express.createServer();
var io = socket.listen.app();

io.sockets.on('connection' function(client) {
  console.log('Client connection established...');
});

Then you need to include the library and do similar setup on the client side...

// inside your index.html (presumably loaded somewhere with express)
<script src="/socket.io/socket.io.js"></script>
<script>
  var server = io.connect('http://localhost:8080');
</script>

Sending Messages

You can send them either way. Here's an example from server to client:

// app.js
io.sockets.on('connection', function(client) {
  client.emit('messages', {greeting: 'Hello, client!'});
});

And to receive it:

//index.html
var server = io.connect(URL);
server.on('messages', function(data) {
  alert(data.greeting);  // will pop up saying, "Hello, client!"
});

Broadcasting to every client

One neat thing that socket.io can do that a traditional websocket can't do so easily is broadcast a message to every client.

client.broadcast.emit('messages', data);

Saving and retrieving data on the socket with get and set

client.set('location', 'Rome');
client.get('news', function(err, updates) {
  //do stuff with updates
});

Level 7

Redis is a key value store. It's much faster than a traditional relational database on big data sets but it doesn't store deep data structures, just keys and values. It offers strings, lists, sets, sorted sets and hashes, but no nested structures. Most importantly, Redis is non-blocking, so you your node app using redis won't be halted while retrieving data.

The Redis website has a fantastic interactive reference where you can try out the commands as if you were in a REPL. It's so good that there's little need to take notes on any of the commands.

Setting up Redis

I would have added to Code School's instructions a bit lacking here. You need a few installs to start using Redis comfortably--

  • redis - the library itself
  • redis-server - the server that you have to start for your node program to be able to access the db
  • redis-cli - the command line interface so you can inspect the database and experiment while figuring out how to make your node app do what you want it to do

Get them all:

npm install -g redis
npm install -g redis-server
npm install -g redis-cli

Basic usage examples

var redis = require('redis');
var redisClient = redis.createClient();

redisClient.set('PI', 3.14159265);
redisClient.get('PI');   // -&gt; 3.14159265

redisClient.lpush('World Wonder', 'Great Pyramid of Giza');
redisClient.lpush('World Wonder', 'Hanging Gardens of Babylon');
redisClient.lpush('World Wonder', 'Statue of Zeus at Olympia');
redisClient.lpush('World Wonder', 'Temple of Artemis at Ephesus');
redisClient.lpush('World Wonder', 'Mausoleum of Maussollos at Halicarnassus');
redisClient.lpush('World Wonder', 'Colossus of Rhodes');
redisClient.lpush('World Wonder', 'Lighthouse of Alexandria');

redisClient.lindex('World Wonder', 6);  // -> 'Colossus of Rhodes'
redisClient.lrange('World Wonder', 2,4);  // 2nd, 3rd and 4th elements, ->
//['Hanging Gardens of Babylon', 'Statue of Zeus at Olympia',  'Temple of Artemis at Ephesus']

Since there are only a few data types and the querying options aren't so complex, learning Redis is pretty simple compared to something like MySQL or mongoDB.

This is a collection of my notes on Code School's, Realtime Web with Node.js course. I posted notes on levels 1-3, yesterday. They covered setting up a node server, using curl, read streams and write streams.

Level 4

You can import external modules by using require('somemodule');. Exporting is done by setting the variable exports to some function. You can also set properties of exports to functions. Here's an example that shows both:

// "awesomod.js"
var awesomod = function(str) {
  return str.replace(/okay/, 'awesome');
}

var yawp = function() { 
  console.log("Awesome!");
} 

module.exports = awesomod;
module.exports.yawp = yawp;
// "index.js"
var awesomod = require("./awesomod");

s = "I'm okay.  How are you?";
console.log(awesomod(s));
awesomod.yawp();

Since we exported the function awesomod directly, that is what is called on line 5. It replaces the word "okay" with "awesome". The yawp function was attached onto the module with module.exports.yawp = yawp;, so it's found at awesomod.yawp

Using NPM

The Node Package Manager is great! It works just like apt-get or ruby gem. It goes out onto the internet and fetches the stuff you want to install. The basic syntax is

npm install somemodule

Afterwards you can access that package inside your javascripts with require('somemodule');, as shown above. Note that when there's no ./ in front of the module name, node will look for that module inside the default directory where NPM installs them.

To install programs you can run from the command line, such as coffee script, for example, use global -g flag.

nmp install coffee-script -g
coffee someapp.coffee

Setting up dependencies

By stating what dependencies your node app needs, you can use a single NPM command and it will go out and get all the modules on your dependencies list and the dependencies for those modules. Dependencies are specified by adding an object to a file package.json in your apps root directory. Here's an example of a basic package.json:

{
  "name": "The Okay App",
  "version": "1.0.0",
  "dependencies": {
    "express": ">=2.0.0",
    "redis": "~0.7",
    "ejs": "~0.7.1"
  }
}

There are a lot of options for setting up your dependencies.
= exactly that version
> higher than that version (Dangerous since the API could change!)
>= same or higher than that version (Dangerous!)
~0.7 at least 0.7 but less than 1.0 (Dangerous!)
~0.7.1 at least 0.7.1 but less than 0.8.0

After this package.json file is in place, just run one command to get them all:

npm install

Level 5

Level 5 was all about using Express.js, and for me it was the best part of the entire course. Node.js is very low level, which is great for making file uploading tools or simple chat programs or backend pieces of huge systems that need to run asynchronously... but it's a ton of work to do stuff like say making a database-powered website. The 15 minute "build a blog" demo that made such a big splash for rails would be a pain to do in Node.js directly. Express solves a lot of this pain. It's built on top of Node.js and provides help with routing, a template system for making views and a few other things. It certainly doesn't do all the things rails does for you, but it does a lot. From what I understand, it's more similar to the Sinatra framework.

Start the server and serve index.html:

var express = require('express');
var app = express.express.createServer();
app.get('/', function(request, response) {
	// __dirname is the current directory
	response.sendFile(__dirname + "index.html");
});
app.listen(8080);

Route Parameters:

app.get('/users/:name', function(req, response) {
	var name = req.params.name;
	// do stuff with the :name we read it...
});

Templates

Express Templates are .ejs files and they work just like the .erb files in rails -- Most of it is HTML, but the stuff between <% tags %> is executed as javascript and javascript between <%= %> tags gets printed on the screen. The blocks between these tags has access to parameters passed in from the server. In this example an object with names and friends is passed to the template:

// app.js
//...
response.render('users.ejs', {name: name, friends.fr});
//...
// users.ejs
<h1>Welcome, <% name %></h2>
<ul>
	<% friends.forEach(function(fr){ %>
	<li><%= fr.name %></li>
	<% }); %>
</ul>

This render a page for each users/1 that greets user#1 by name and has user#1's friends listed in an unordered list with one item generated with a name on it for each friend. At users/2 a page will be rendered that greets user#2 and has user#2's friends and so on for every user the app has stored.

Since moving to San Francisco, I've realized that despite its attractive market for start-up investments, Beijing is something of a tech backwater outside of a few companies. Not only are people here using a lot of technologies such as Ruby on Rails that are almost unused in China, but they're also crazy about a quite a few things I'd never even heard of while working at a fairly hip mobile start-up in Beijing. Top on that list was Node.js, so I worked through the free Node Beginner Book and then took Code School's course on it. Their interactive system is great for learning, but I still find the need to have some review notes to help it sink in. Here goes:

Level 1

Curl is useful! Why didn't I think of that? After setting up your Hello World server with this in your server.js:

var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8080);

There's no need to bother firing up a browser. You can verify the server's running with curl!

curl http://localhost:8080

Level 2

You can add a second listener for requests if you want to:

server = http.createServer(function (request, response) {
  // do stuff
}).listen(8080);

server.on('request', function(request, response){
  // 2nd listener
});

Since http.Server is an event emitter and http.createServer takes a requestListener as a parameter and requestListeners are functions that automatically listens to 'request' events, these two are identical:

http.createServer(function(request, response){ ... });
// is the same as
var server = http.createServer();
server.on('request', function(request, response){ ... });

The second syntax above is how we usually add our own event listeners in node.

Level 3

Read streams and write streams are event emitters. Request is a read stream; response is a write stream. You can make them do stuff with

somestring.on('someevent', function(data){...});

File Copying

var fs = require('fs');

var file = fs.createReadStream("somefile");
var newfile = fs.createWriteStream("somefile_copy");
// Pipe handles read/write speed mismatches for you
file.pipe(newFile); 

Handling back pressure manually if you don't use pipe

Unfortunately, there's the risk that the stream that's writing data out can't keep up with data that you're reading in. If memory fills up and more data keeps streaming in, bad things happen.

We can check to see if a writeStream's buffer is full with var bufferokay = writeStream.write(chunk);. If that returns false, you can shut down the readStream with readStream.pause(). Then once its buffer is empty writeStream will automatically send a 'drain' event. By listening for it and using a callback to readStream.resume() we can make sure the stream starts reading again once we're ready.

var fs = require('fs');

var file = fs.createReadStream("HUGEFILE.avi");
var newFile = fs.createWriteStream("HUGEFILE_copy.avi");

file.on('data', function(chunk) {
  var bufferokay = newFile.write(chunk);
  if (!bufferokay) { file.pause()}
  newFile.write(chunk);
});

newFile.on('drain', function(){
  file.resume();
})

file.on('end', function() {
  newFile.end();
});

I've just started getting into meteor, customizing their tutorials, but this technology is awesome! Try this:

  1. Go to my leaderboard page I uploaded and open it in two chrome windows.
  2. Play around incrementing the various scores for each of the scientists. You'll see the other window update almost instantaneously.
  3. Open the JS console (by hitting ctrl-shift-j), and enter Players.insert({name: "Leonardo Davinci", score:60});.

This will update the js in your browser window... and the server will store updates and push them back to the other window! Is that cool or what?

Best of all, is it barely took any code-- html:41 lines, js:61 lines, css:62 lines.

Go to meteor.com to learn more!