Saturday, October 1, 2016

You Should Meditate

Meditation. It's an arcane and still somewhat esoteric world that a lot of people are intimidated by, or dismiss thanks to the less "grounded" practices that are often associated with it by those whose practice. Fortunately, that stigma is waning as a more scientific backing is developed, and people of power come out to discuss to their practice.

I've been meditating for quite a short amount of time - only about 2 years now. My practice is also fairly relaxed - 10-20 minutes every day. Despite that, or perhaps because of that, I'm a huge advocate of it and am often asked to share my motivations and experiences.

It's quite difficult to relay that information in absolute sense - it's not like physical training where we can often attribute a set of values to our progress (squat weight, mile time, throw distance). It's far more subjective than that, because the way we experience ourselves and our own minds is too fundamental. It's difficult to subvert that, and discussing the practical benefits of meditation is like discussing weight training only in terms of strength gains. The effects are deeper rooted, and such a practical explanation is only addressing the high-level manifestation of what is really happening.

So, the short of is: just try it for awhile. Trust the studies and rational, successful people who advocate it.

Below is an email I recently wrote to a good friend of mine's mom. She asked me to describe what it is I have gained from meditation. I attempted to mix in the practical with the fundamental, and stand by it being as good as an explanation as my current experience allows me to provide.

---

Hey ___,

I'd be happy to [discuss my experience with meditation].

Book wise, the books that I used to introduce myself to meditation and mindfulness were:

10% Happier
- This book outlines the journey of Dan Harris (some new anchor) as he discovers and learns about meditation. The book is somewhat slow-paced and verbose, but it’s a good read and an effective way of understanding meditation, as he generally guides you through his own past learning experience.

Real Happiness
- The book is much more informational, and focuses on philosophy and techniques. This book will guide you through a routine that you can repeat indefinitely, and will expose you to many different forms of meditation. If you had to choose any one book to read, this is it.

Buddhism Without Beliefs
- Purely philosophical, this book outlines some core teachings of buddhism without the religious aspect. I read this after already being somewhat familiar and experienced with meditation, and it helped me take my experience further.

There’s plenty of pretty stellar books out there, and I believe 10% Happier comes with some recommendations as well. I feel it’s incredibly important to do this reading and familiarize yourself with the underlying philosophies of meditation - going into it blind will likely leave you confused and discouraged.

I’ll give my take on meditation and what it means to me, but I’ll start by saying it’s a very subjective experience. Meditation hits very core components of the mind, and the way it gets expressed at a conscious level is very dependent on the individual. So, with that in mind, here’s why I do it and what it means for me personally:

I used the terms benefits before, but in reality I think that’s a poor way to describe meditation, as it doesn’t quite focus at the core of what we’re trying to accomplish. Benefits are more symptomatic. What we’re trying to do with meditation is strengthen our consciousness. It’ll take a lot of explaining to express what that means, so I’ll start by listing some things we aren’t trying to do with meditation:

- Relax
- Destress
- "Clear our minds”
- Become monks

In fact, despite the way people like to title their books, I don’t even see meditation as a way of achieving “true happiness."

As a human being we’re always in a state of contention inside ourselves. There’s these two warring, etherial sides of our minds; we often notice them when they clash. We know we shouldn’t eat that - but there’s a part of us that overwhelms, and we can’t resist. We know we should sit down and get some work done, or get up and go exercise, but there’s a part of us that overwhelms, and we can’t turn the TV off. We shouldn’t get angry, but there’s a part of us that overwhelms, and we can’t help it. We know we shouldn’t have prejudice, but there’s a part of us that overwhelms, and we express it anyway.

We notice these parts of ourselves as they clash, which I think paints an overly negative picture. People often talk about “overcoming” or “defeating” that part of us, but I don’t think that’s quite the right idea. That same part of us is what makes us feel happy or in love, and what gives us insights and empathy. It’s our “subconscious", and it comes as a “package deal”. We don’t really get to choose what gets shoved into our conscious mind, but we can choose how we react to it, or if we even react at all.

In a sense, meditation is about strengthening the partition between our conscious, high-level thought, and that subconscious pit that burps out thoughts and feelings. By doing so, we can better control how we react to those outputs. Meditation helps us understand the architecture of our mind, and the properties of our thoughts. In the end, it helps us control our mind.

I won’t go into exactly how meditation accomplishes that, since those are details that you’ll learn through reading as well as subjectively through the practice itself. I’ll give you a few practical benefits that I feel in my day-to-day life:

Mindfulness
Mindfulness is the state of conscious engagement in the present moment, and cultivating it is the goal of many meditation techniques. Mindfulness is a halting of the storm of thoughts in our mind at any moment to maximally enjoy the very state of being alive, right now. I think of mindfulness as a “child-like state”. As a kid, we’re very engaged in everything that happens around us. Everything is interesting. As we age and things become familiar, we recess into our own minds and let most of our moments pass by un-noticed. The lack of engagement in the present-moment is, in my opinion, a large factor in why we perceive the acceleration of the passage of time as we age.

Another state of mindfulness you might be familiar with even today is that of “flow”. “Flow” is the state of maximum focus, where we’re completely engaged in the task at hand. You may experience it while playing a sport, or working on a project you really enjoy, or immersing yourself in a book.

Before I started meditation, I would have these strange moments of actualization, where I realized I had been operating on auto-pilot for the past several days. I could never quite articulate it, but I felt that I hadn’t been conscious in quite some time, up until that very moment. Talking with others I’ve come to understand that this isn’t particularly uncommon. I would come to understand this as mindfulness.

Mindfulness is not something I personally experience 24/7. A persistent state of mindfulness is the goal of gurus and monks, but for us, we hope for mindful moments: the ability to calm our minds for a few moments, and just enjoy being alive. Then, we get back to what we need to do. Mindful moments can occur anywhere such as driving, walking, or falling asleep (these are most common for me).

I’m a very future-oriented person. I’m always thinking about growth and improvement, and where I want to be months, years from now. Mindfulness is important to me because it allows me to put that aside, even for a few moments, and just enjoy the state of being alive. You can’t enjoy life if you’re always looking ahead.

Calm
By understanding the nature and origin of our thoughts and feelings, we can better identify and respond to external circumstances. Stressful or angering situations can be tempered by our own control over our emotional state. As conscious beings, we can control how we feel, and what we do with those primal reactions that bubble up from our subconscious. By training that control through meditation, I find I can react much more logically and effectively to situations in my life. I can put aside my ego when confronted with a mistake, I can have empathy and patients for a irritated coworker, and I can be better content in states of pain or discomfort.

Control
Like I mentioned before, these clashes that occur in our minds can prevent us from doing things we know we should be doing. Before meditation, these conflicts are entirely free to resolves themselves, with the strongest inclination winning. Sometimes we feel particularly motivated and we can overcome our hesitation to exercise, sometimes we don’t and we fail. With meditation, we shift the power to our ability to logically choose what action we wish to take. You may very well chose to stay in and skip your workout today, but the important thing is you chose, consciously and logically, to do that. You didn’t just do what you “felt like doing”. Of course, you better have a good reason for skipping your workout :p - but that’s an accountability you’ll be able to hold yourself to over time.

Growth
This is more of a combination of the above benefits. When you put the ability to be calm, and in control, while simultaneously having a deep sense of what it means to be alive and present, what you get is an ability to grow while enjoying life as it happens. This is the #1 factor for me and what drives me to meditate every single day.



Cultivating your conscious mind through meditation is like putting on glasses after a lifetime of blurry vision. I would never, ever, stop meditation and would recommend it to anyone under any circumstance. It’s exercise for the mind at the end of the day, and it’s shocking to look back and think about how out of shape you were.

Like all exercise, it takes effort, consistency, and time. Meditation can be tedious, boring, strenuous, and difficult. It can also be relaxing, enlightening, and energizing. But, after you do it every day for long enough, you’ll never stop.



Surprisingly, it doesn’t take a massive time commitment to meditate. I personally spend 10-20 minutes every day meditating. It’s not a lot, but what’s important is that it’s done every day, and that you’re familiar with the philosophy and purpose. I do a few different forms of meditation, all of which I learned in Real Happiness, but primarily a very simple, zen breathing meditation. I recommend you follow the routine that book outlines for you and then chose your own routine from there.

Anyway, that’s a summary of my thoughts on meditation. Apologies for the length: it’s hard to succinctly describe these things because I do think they’re very fundamental and profound. Please let me know if you have any questions!

- Nick

---

Since sending that email, I've also been made away of some stellar Apps that work to guide new practitioners through the meditation, slowly introducing concepts and philosophies. Apps such as Headspace and Calm seem to be the most popular at the time of writing this.

I think Apps and programs like these are great, although one should be cautious about developing a dependency on guided practice. Much like a personal trainer in the gym, it's a great way to be introduced to that world and to ensure you're engaging in it properly, but once that familiarity is established it's best to forge on independently. That resource will always be available to you if you feel the need to go back and reconnect with that guidance.

Monday, December 29, 2014

Getting People to Be Better

I’m obsessed with self-improvement. I like to think of it as a more productive form of narcissism. I don’t spend much time staring into mirrors or having power fantasies, but I do spend an inordinate amount of time thinking about how I can be better. Be it the tools I use, the technology I pursue, exercise, or even recent forays into the world of meditation and mindfulness, I always try to have some “construction site” in my self that is making me better. To me, stagnation is the enemy.

Watching these changes occur in myself and slowly becoming the person I want to be is one of the most deeply gratifying experiences of my life. I see the benefits in myself, and can’t help but turn that introspective lens around. Perhaps the second most gratifying experiences in my life come from helping others in the same way I try to help myself. I love sharing knowledge. It’s how humanity progresses.

In this post, I want to share my experience with sharing knowledge, and encouraging others to develop skills that I think would improve their life. This is simply the most consistent approach I’ve derived from many failed and successful attempts.

The obvious question has probably already come up: what business do you have pushing your experiences onto others?  If there’s one thing you take away from this post, it’s this: none. There are very few things more unwelcome than undesired help. The very first checkbox in getting people to be better is asking yourself whether or not this person could legitimately benefit from your help. Or, more practically, if they even give a shit.

Let’s take the text editor war as an example. If you’re like me, you probably started off using a good, but basic text editor like Sublime Text. I was productive enough, and didn’t see a need to change. Every time somebody would insist that Vim or Emacs were superior, my internal response would always be the same: go away. No degree of compassion or pedagogical skill would have steered me away from Sublime, because I didn’t care.

The most important factor in sharing improvement is being welcome. At the end of the day, their drive has to come from within. Pushing your practices onto others will never work. Instead, make non-threatening suggestions. Discuss your alternative way of doing things, and how it’s benefitted you. How did meditation help you? Why do you think the month-long Vim learning-curve is worth it? Don’t push an agenda; pique interest. If that doesn’t work, back off.

Eventually, I did undertake the head-bangingly arduous task of learning Vim. After watching a friend manipulate a Javascript file like a musician, I decided myself to welcome his advice and switch over.

My friend, who we’ll call “Alexa”, was a History major at my university. From when I first met her, I knew that she was smart, driven, and even technically minded. Being in Berkeley, she’s started to hear more and more about coding. People always say it’s worth learning, but she was never really sure how or why to approach it.

Once Alexa shared this with me, I realized I had legitimate knowledge to offer her. I talked to her about my experiences with programming, how it’s helped me, and how I think it could help her. No agenda pushing, no lesson plans, no technical talk. Pure interest piquing.

If you manage to succeed at this, you have to be careful. This is the most unstable period of the learning process. The most common approaches I’ve seen at this point are: (1) going on a huge rant about the subject and why it’s amazing and how you do it and how you learn it and why it’s amazing… (2) passing over a single webpage with a few paragraphs on the topic, then leaving the person in the dust, (3) saying your way is the best and telling them exactly what to do (“learn Python using Vol. 2.0.3.7 of Advanced Python for Air-traffic Controllers…”).

People love to learn. Getting people excited about learning is easy, but cultivating sustainable interest is a subtle and fragile exercise. There needs to be a easy entry point. (1) ignores this by overloading the person with information and immediately diffusing any interest via unintentional intimidation. Next, there needs to be a clear path. (2) ignores this by leaving them to fend for themselves, where they’ll likely lose interest and return their focus to something more familiar. Finally, there needs to be the freedom to explore a little, and personalize the learning experience. (3) ignores this by over-specifying, removing all possibility of creativity and breadth.

The question I always ask myself at this point is this: how did I learn? What was my entry point? If my entry point sucked, what do I wish it was? Your goal is to present a initial, detailed plan that should always leave them with the feeling of knowing what to do next. For Alexa, I suggested a series of Coursera classes on programming, followed by enrolling in some of the University’s introductory CS programs. That’s effectively how I started, after all.

Learning something new is like exploring a blackened cave without a light. Without guidance, trying to understand where you are at first is a daunting and hopeless task. You flail around in the dark, making little progress. The game plan you provide is like taking their hand and putting in on the cave wall, where they can follow it and begin to mentally etch out their surroundings.

Once that hand is on the wall, there is very little you need to or should do. Independence and self-discovery are the keys to learning. Holding onto them and making them feel out every nook and cranny of the cave as you know it will do nothing but confuse them. Guidance can be provided when it’s requested, and you may want to check in periodically and ask how things are going. Connect with them as a mentor, a resource, but don’t helicopter.

I’d see Alexa and ask her how the classes were going. Usually very well (they can teach her better than I can after all), but sometimes she would have a question that I would try to answer. No problem. She was feeling out the cave by herself, understanding what it looked like, and asking for help when she knew she needed it.

Watching your friends go through the path of learning you yourself went through is an awesome experience. Once they start to know their stuff, I try to do one last, somewhat counterintuitive thing: diminish my status as their mentor. The last thing you want to do is keep talking down to them as some absolute word of authority, putting them in a never-ending game of catch-up. Have equal-eyed discussions with them about the subject, besides being mutually beneficial and a ton of fun, helps to confirm their efforts. Of course you can still provide help, but do your best to validate as well.

Alexa decided to change her major to CS, and we still talk about technology and coding all the time. Her excitement about the subject is contagious, and I feel constantly invigorated by her newfound interest. Bringing people into your world is incredibly gratifying. Your experiences and techniques for living life are invaluable to others. Not sharing them is just inefficient; not to mention you get serious return on investment. You should give it a try, but do it right.

Tuesday, August 19, 2014

Coding in the Real World

Tis the season of job hunting once again. Job listings are blossoming and us eager college students have begun to swarm. Resumes are being dusted off, and the sounds of keyboards implementing practice algorithms and data structures fills the air. 

In a previous post, I outlined my experience with the internship application process. I had spent several months embedded in it, and wanted to share what wisdom I had managed to scrape together. What I couldn’t share was the experience of the internship itself. What’s the point of all of this? Is an internship hard? Will I be able to handle it even if I get an offer?

It’s funny how overlooked those questions are. It’s almost suspicious that nearly the entire focus of the internship process is in the application. Amongst the Berkeley community, those who have withstood the trials of an internship seem to radiate this mythical aura from the perspective of those who haven’t. The kids today might describe them as “legit”. People want them in their group projects because they must know so much now.

This past summer I interned at a San Francisco startup called Endless that does really awesome stuff. I want to convey not only my experience, but the experience of several of my friends and colleges that also went through this mythical ringer. How “legit” did we become?

Well, it turns out that the answer depends very much in how you define “legit”. My friends and I are all walking away from internships with the same impression of difficulty: the application process was much more strenuous and challenging than the job itself. Don’t get me wrong, we faced a problem massive in scope and so to were the number of problems that came along with it. Problems of engineering, design, communication, marketing, you name it. It simply turns out that writing code in the “real world” is a very different experience than writing it in the classroom.

The problems you face in the professional world of software production will tend towards design, not concept. This is a very bizarre transition for someone who had learned to code in a college environment. Professors give skeleton code, leaving the details of implementation to us. Writing a program for them isn’t hard once you’ve grasped it conceptually. For example, implementing a modified tree data structure or optimizing matrix multiplication in a multi-threaded environment.

Production code seems to be the opposite. You’re given nothing other than a blank text editor and a list of requirements. Very rarely will you have to employ some mind blowing data structure or algorithm, and even if you do, it will be even more rare that you have to implement it yourself. It’s an exercise more akin to writing the skeleton code itself and then filling in the blanks with libraries and technologies, instead of student code.

The most valuable thing you’ll learn at a internship is simply the process of writing code in a productive way. How to effectively use tools like Git and GitHub. Collaborating with pair programming and code reviews. In school, programming is all about writing code. In the real world, programming is all about talking with other people, and then writing some code maybe.

What about all of those trendy technologies like Node.js, MongoDB, etc? What about APIs? Do you get to learn those? Yes. And they’re easy. Learning MongoDB or jQuery is nothing like taking a class in Databases or Web Design. These technologies are highly optimized to be as simple and magical as possible. They abstract out the difficulty. It’s why they’re popular!

There’s a phrase I ran into once that I think describes the situation very nicely. In school, the requirements of code are easy and the implementation is difficult. In the professional world, its the requirements that are hard and the implementation that is easy. A lot of my friends are intimidated by an internship because they see the difficulty of the interview process and believe that they have nothing to offer. Or, they believe that the difficulty of a computer science education is analogous to the work of a programmer. Forget about that. Getting an internship means that you are more than capable of handling the work.

This isn't to say that the work is easy. Most of us became interested in programming due to the challenges it so often provides us. As a student, you will be forced to constantly learn and grow and build upon your knowledge. Funnily enough, this doesn't change much once you leave college; it's just different. Conceptual rigor gives way to domain familiarity, and your obstacles become less about your intellectual limitations, and more so your willingness to plan ahead and become familiar with new tools.

With all of this in mind, my advice for a successful internship is this: be friendly, collaborative, inquisitive, and willing to learn. Don’t be afraid to voice your confusion or lack of knowledge. An internship is a training program in collaboration and software development. You aren’t expected to be a genius, or even know anything about their particular technology stack. Learn as much as you can. 

You won’t come back to college and destroy your compilers class because you’ve ascended into your planar coding form. Instead, you’ll be comfortable organizing the GitHub repo, know the best practices for organizing your code and keeping it readable, have intelligent and iterative code writing habits, be familiar with different coding models and project structures, be willing to review your friend’s code having confidence that you can help, and be a leader amongst your class project group.

If you’re at the point where you’ve got the offer and don’t know what to expect, relax, because you have nothing to worry about. If you’re still working on that offer, relax, because it’ll never be harder than it is now.

Tuesday, April 22, 2014

I Wrote This Post With My Mind (I Wish).

Looking back on those ridiculous old-timey predictions of the future is becoming increasingly surreal. Five years ago I would laugh at their naiveté, but recently it's become more humorous how much progress has actually been made towards those visions (FaceTime anyone?). Strides in AI have rendered movies like “Her” something that could be described as a relevant comedy. Machine learning has made Facebook more apt than us at recognizing human faces; something bred into our very neural circuitry.

I had the pleasure of installing a floppy disk drive for the very William Kahan today. He explained to me the technical limitations of his day which led to delightfully hacky quirks such as the shameless twist in a floppy drive IDA cable (a remnant of the A-B hard drive configuration of old Intel computers, apparently). It all sounded so much more makeshift than it is today. I couldn't help but think: “it's a pretty chill time to be alive.”

While that's all well and good, we're not going to talk about lame things like life-saving medicine, unbelievably powerful mobile phones, or automated cars. We're talking about the real important stuff: videogames.

On the advent of the Oculus Rift, Omni, Leap Motion, it's pretty safe to say that it's an awesome time to be a game developer. It's a kind of “wild west” situation that we haven't seen since the dawn of 3D-graphics. The excitement is obviously well earned, and will usher in a freaking awesome phase of immersive entertainment. Of course, you've heard this all before.

Something's missing. Those old-timey predictions never included us swiveling around in a chair with an awkward looking headset on, mouth agape like we're trying to attract a family of meerkats (they stick their head in your mouth to smell you; you didn't know that?). What did movies like Tron predict about our virtual reality future? What's the final frontier? Simple: full mental immersion. No controllers, no physical limitations, just a headset and a transplantation of our consciousness into the virtual world.

Don't get me wrong. We're very close to insanely deep immersion with things like the Oculus, and not so close to the Tron reality. That being said, there's no reason why we can't start trying to reach it.

A few weeks ago I had the privilege of participating in the Intel Wearable Games Hackathon in San Francisco. There I got to play with the new Galileo (it seriously sucks and that's all I say about that) and do what I love to do: make games. I was persuaded to go by my friend John, who's a cognitive-science major here at UC-Berkeley. We had been playing around with Arduinos, and John had been looking into EEG hacks. We took a crappy Mindflex headset he had soldered to an Arduino and decided it would be pretty sweet to base a game off of it.

John suggested a mind-controlled Tetris variant, which would have been an awesome modification to my Tetrocity project, however we ended up going with a more realistic vision of making a Warioware style game in which the player is prompted with a series of quick challenges, which we would tailor to the EEG. We eventually stuck a few more sensors on there, like a heart-rate monitor and pressure sensor, as an attempt to create a game around the mastery of your biosensory data. We called it the Mind Body Fitness Challenge.

Unfortunately the build wasn't very well documented. There's source code on my Github which isn't very interesting. It worked okay past some Galileo setbacks and the inherent poor quality of the Mindflex headset. What was really surprising was the amount of interest it generated. We were invited to present our project at the Intel 2014 GDC, and even to an incubator for the sake of turning the project into a real product. A few days ago we were invited to host a booth at a health fair. Like I said before: this thing barely even works.

Brain-based virtual reality isn't some far fetched pipe dream for loony futurists anymore. Technology has reached the point of absurd innovation that what was once reserved for the fantasy realm of Tron is capable of generating real interest, because it's actually possible. Or at the very least, it seems like it could be.

Neurohacking is very much in its infant stages. A new group on my campus is dedicated to cognitive technology and finding uses for the slew of new, powerful EEG headsets hitting the market like the Emotiv. It's a weird experience. There's so many applications, but nobody has really touched it yet. It's like a gold mine for inventors. For example, my friend John wants to change the way we test for impairment by using brain waves themselves instead of secondary indicators. Others want to track your circadian rhythm throughout the day so you can optimize your sleep schedule. I want to control videogames with my mind.

Imagine the layer of depth that could be added to a game like Amnesia. Imagine running for your life, scrambling into a hiding spot and trying like hell to calm down because the monster can smell your fear from the EEG and track you down. Imagine manipulating an entire game world so that your friend can literally explore your mind-scape (credit to my friend Niko for that idea). It's all very very cool.

Is any of that currently possible? Well, no. EEGs are very limited in what they read, and extracting meaningful information from them is a salty experience at best. Not to mention, they're way too expensive for commercial use. But, wasn't the same thing said of visual virtual reality 3 years ago? Now everybody is jumping on that bandwagon. Interest is what pushes industries forward.

There's clearly interest in neurohacking, so why isn't it a more popular sector of VR? Most likely because there isn't a tangible experience out there that's fueled by it. The technology simply isn't good enough. It's an awkward situation. To generate interest, you need to show that it has power. To show that it has power, you need the technology. To get the technology, you need interest. It really makes you appreciate the difficulties and risk faced by companies like Oculus.

I think neurohacking itself will eventually overcome the hump by hackers taking advantage of the Emotivs of the industry. Once we can show that even a primitive EEG can change the way we interface with technology in a deep and fundamental way, the technological innovation will explode. Maybe that application lies in videogames, maybe it doesn't. Either way, I'll certainly be trying my best.

The big question to ask is whether or not neuro-based technology is even worth bothering with at all right now. If we're some unknown distance away from viable, consumer-grade neurofeedback technology, then shouldn't we just ignore it until it actually happens? I would say no. Current EEGs are noisy and inconsistent, but we don't need to build technologies around current EEGs. If we accept that EEGs will approach some arbitrary degree of accuracy, then why not just build around that assumption? The only risk we run is that assumption proving false, which the very development of the technology will prevent.


Stay tuned for my brain-wave based survival horror game, Epinephrine. ETA: *cough cough* 

Saturday, January 25, 2014

On College Party Culture

The semester is fresh and Berkeley is slowly waking up from its winter stasis. The streets are packed and loud with students looking for a place to party.

The more time I spend in college the further removed I feel from that mindset. I certainly had it as a freshman. As someone who's always preferred a night relaxing with my buddies (or even on my own) than raging, I really wonder why I felt that way. How many of these freshman trying to get into my fraternity's party really want to be here?

I think nobody will need convincing that this comes from the popular image of college life, which we see in movies, TV shows, songs, liquor commercials, etc. At the end of the day watching a raging college party is way more entertaining than seeing a few friends study in the library, even though the latter is probably a more accurate representation.

As is typical for the pop-culture industry, it's also about selling you something: an image. An image which you have to live up to if you want to "do college right", and which you may have to buy a few brand-name liquors and albums to achieve.

First things first. There is nothing wrong with participating in the party culture. Seriously. Tons of people genuinely enjoy it and that's fantastic. If you're one of those people: party on.

Unfortunately, I'm not. While I had a lot of fun pledging my fraternity, my biggest regret in college is forsaking my studies that semester and permanently dropping my GPA 0.5 points. It's closed a lot of doors. I'd wager that a great deal of college students are also not willing participants of the college party culture and are facing an enormous amount of pressure to conform to it.

The irony is that college is about the complete opposite of what the party culture promotes: individual development. Not just academically, but development of every aspect of your persona.

I've found that there are four critical rules to maximizing your time at college: study hard, socialize, be physically healthy, and enjoy life. Do these however you want, but do them.

This is where party culture becomes damaging. Will partying help you be social? Definitely. But what about the rest? Studying? Definitely not. Physically healthy? Hard to say, but given the calorie intake of liquor we'll go with 'probably not'. Enjoyable? Entirely depends on you. If you're like me: not really.

College party culture promotes a lifestyle that is not only not universally enjoyed by those that are pressured to participate, but also damaging to the college experience in general. When I look back at how I've spent my time in college, I value the nights gaming or watching movie with my few, close friends far higher than partying at my fraternity. I've skipped tons of nights on frat row to spend it in San Francisco with my girlfriend and I've never regretted it once.

College is about becoming your own person. Don't let anybody or any body dictate how you should do it.

Friday, January 10, 2014

How to Interview for an Intership

These past few months I've been interviewing for an internship. For a lot of people, there's nothing special about this. Most of my close friends have done dozens of interviews already, but the experience was brand new to me. In fact, before November I had only ever done 2 interviews in my lifetime: one for Stanford, and one for my part-time job. I found the internship interview process very stressful, likely as a result of having such little experience with it all. You always want to know as much as possible about something you're getting into, but the nature of interviews seems to make this impossible.

This post is for the me of two months ago. Or at least, people like the me of two months ago. I want to share some of the nuggets of wisdom I gained by going through the motions, and ways you can prepare yourself. First off, I could end this post by deferring you to two books: Cracking the Coding Interview and The Google Resume. Both are by the same author, and both are great. If you have the time to make your way through these books, I highly recommend you do. You'll be mega prepared.

Preparation
Perfect your resume

This step seems obvious, but you should be aware that resumes in the tech biz differ a lot from resumes you've probably made before. Things like work experience are generally weighed less heavily than things like coding projects. Academic achievements are fine, but recruiters are going to be more impressed with your interaction and contributions to the "real world".

One of the main concerns I encountered while perusing interview advice was the impression that you haven't "done" anything, or that you haven't learned enough to be able to offer anything in particular. I have several friends who didn't even try because they thought they were so unqualified that they would just be wasting their time; that their resume would be tossed out immediately.

First off, this is almost definitely false. If you know basic algorithms and data structures (the second programming class I ever took), you're ready to interview. A close friend of mine will be interning for Facebook without a single college project on his resume (his GPA is stellar to be fair). At the very least, there's no harm in trying. Companies aren't like colleges. They won't hold it against you if you apply and get rejected. In fact, you're usually encouraged to try again, as they know you have the potential to grow as a coder.

If you really want to beef up your resume, try to work on something outside of the classroom. There's nothing wrong with putting class projects on your resume (as an intern you aren't expected to have tons of experience), but independent projects usually take precedence. One way to beef up your list is to take a project you've done in school and expand on it in your own time. I've had to program several games throughout my time in college, and it would be pretty simple to go back and add my own features, or implement a GUI, etc.

Another thing you can do is get involved with open source projects. You can find tons of these with a quick Google session, and there are almost always opportunities to contribute for all skill levels. Check out VLC Media Player for a good starting point.

The best thing you can do it think of a project you'll be passionate about and just do it. Not only for your resume, but to enjoy the process and learn as much as you can. I spent 3 intense weeks coding a game idea I had (Tetrocity), and it eventually became a main talking point of a lot of interviews. Even when it wasn't, a lot of the concepts and nuances I had learned in the process of making it came up.

This subreddit was also a great resource for me when I was working out the kinks of my resume. There's a ton of examples and experienced people willing to help out.

Prepare your expectations

This step is not so obvious, but is a harsh reality of the process. I once heard a quote along the lines of "apply for 30, interview for 7, get an offer from 1". The numbers will obviously vary based on your abilities, but the main point is that you need to prepare for rejection. In fact, you need to prepare for a lot of it. I was fortunate enough to get an offer from my favorite company, but I was rejected quite a few times elsewhere. If you aren't ready for it, it can be pretty disheartening.

First things first, a rejection does not always mean you "failed". Sometimes it does, and you should see those as opportunities for improvement, but a lot of the time the decision will simply be out of your control. I've interviewed for positions I didn't have the experience for, done well, and then been rejected because I didn't have the right experience. Oh well. I've been rejected because I wrote a code base that the company didn't take the time to read properly. Oh well.

I'm not saying you shouldn't take responsibility for negative outcomes. I could have made that code base more readable. The point is that rejections aren't the end of the world. They're an opportunity to learn and be better prepared for the next time. Say "oh well", learn from your mistake, and move on.

A direct consequence of all of this is that you need to apply to a lot of companies. A LOT. The competition is fierce and unless you're a rock star you don't want to put all of your eggs in one basket. It doesn't even matter if you aren't really qualified. Just apply anyway.

Apply correctly

This is one of those areas that I don't agree with, but it's how things go. The best piece of advice I can give in this regard is to avoid applying online. You're chances are simply much better if you can give your resume directly to a recruiter. If you go to college, attend your info sessions and career fairs. If not, look for events put on by companies and attend them. Try to find connections to the company. If you have a friend who has a friend that works at a company you like, ask to be put in contact. A lot of employees of tech companies are actually rewarded for referring a candidate, so they'll be more than happy to help you out.

If you can't do any of that, it isn't the end of the world. I found and applied to the fantastic company that I will be interning for on an online job listing website. In this case the idea of applying to as many companies as possible is even more important. Your chances are less, so increase your sample size!

Know the company

There really isn't a faster way to disappoint your interviewer than not knowing what their company does. It's in both your and the company's best interest if you are applying not just because you want a job, but because you find their work particularly interesting. Companies usually have tons of information online, so take the time before an interview to learn as much as possible. This will also help you ask intelligent questions and really get a feel for what the company is like. It's important that you'll be happy there!

Practice practice practice

I found that there are three main types of interviews: who-you-are, do-you-know, and can-you-do. You'll usually have many interviews per company (anywhere between 3 and 12), and how many of each type you get completely depends on the company. In any case, try to do your best to prepare for each.

Who-you-are interviews (aka "behavioral") are conversations about you as a human being. You'll be asked about your life, background, hobbies, experience, goals, interests, etc ("what kind of software do you like to write?"). These are meant to form a picture of who you are and if you'll fit into the company. There's no better advice for these interviews than to simply be honest. Acting like someone you're not just so the company will like you is only going to hurt everyone in the long run.

Other than that, simply be prepared to talk about everything on your resume (this shouldn't be too hard). Mock interviews are great for this.

Do-you-know interviews are akin to a game of programming trivia. You'll be asked a good deal of relatively factual questions ("what does the Java finalize() method do?"). While a lot of these questions will be 'you either know it or you don't', there's nothing wrong with making an educated guess if you're stumped. Sometimes deducing the correct answer is even more impressive than simply knowing it.

The subject of these questions is pretty dependent on the job qualifications. I've found that a lot of "general" internship programs will include questions about Object Oriented design, and language-specific questions for Python, Java, and C. To best prepare for these, make sure you're very familiar with your favorite language and don't claim to know something you don't on your resume. Brush up on your data structures and algorithms (including implementation features such as Java's HashSet load factor) and know their complexities. Also, pay attention in class!

Can-you-do interviews are harder to prepare for. They usually follow the do-you-know interview and involve you solving a problem on the spot. These questions can range designing an entire program to developing a single algorithm ("how can you check if a player has won a game of tic-tac-toe?"). The best way to prepare for these is to simply practice with as many of them as possible. Check out the two books at the beginning of this post for some great sources of practice problems. I made it my mission 3 months before my first interview to do 2 practice coding questions a day, and it helped immensely. CareerCup is another great source of questions and active discussion. Remember to try and do these with pen and paper or a bare-bones text editor. You won't have Google or Eclipse auto-complete in an interview.

The Interview
Deal with nervousness

My friends seem to vary wildly on how nervous they get for an interview. Some freak out, some don't seem phased at all. I'm certainly closer the freak out side, so I have extensive experience in dealing with nerves.

The first thing you need to do is understand that even if the interview goes terribly, you will still be proud of yourself for trying. It's like getting rejected by your crush. Hey, at least you tried. You can't get an internship if you don't interview, so overcoming your nerves and going through with it is doing yourself a huge favor.

My second piece of advice is go into it with zero expectations. When I was younger I used to try and prepare for every possible outcome of a stressful situation so I could be prepared for anything. This is bad. Don't plan what you're going to say or how you're going to act. This will make it incredibly hard to act naturally and 'lose yourself' in the moment. Just be yourself. You're great!

Something that helped me immensely is to try and connect with your interviewer on a casual level before the technical portion begins. They're people too, and usually incredibly kind and fun to talk to. Spend the first few minutes making small talk if you can (some interviewers jump right into it, so don't force it). It'll help you be more comfortable with your interviewer and the process will seem less daunting. This also has the added benefit of giving you insight into the company's culture, and can entirely change how you perceive a them. Do you really want to spend your internship working with people who aren't friendly?

Above all else, the nervousness will diminish with experience. It's like taking an exam in college. The first time is mortifying, but loses virtually all stress over time.

Think out loud

When you're asked a do-you-know kind of question, it's almost guaranteed that you won't know how to do it immediately. Don't panic. The point is to see how you think through the problem. Keep your interviewer informed with what you're doing. Saying things like "my first thought is this...", "I'm not sure if this will work out, but I'm going to try this...", or "I don't see a solution right now, but I'm going to work through this example to figuring something out..." are a fantastic way to do this. At the very least, your interviewer can't help you if they don't know what you're doing!

I should say that there is a fine line here. Don't babble and talk for the sake of talking. Long periods of silence are absolutely fine. Do what you need to do to think clearly and figure it out.

Don't panic

I can't tell you how many times I've heard "I thought I did terribly, but I got the offer!". It's really easy to walk away from an interview thinking you failed if you didn't answer everything. This is totally false. If the question is hard, then the chances are most other people didn't it either. The point is to see how far you got, or what your process was before you got stuck. A hint isn't the end of the world. If you can't figure something out, don't worry. Just stay calm and tell your interviewer that you're stuck. They'll want to help and will usually guide you in the right direction.

You're being evaluated relative to everyone else, so think of it like a curved test. A 60% may still be an A+.

Ask questions

Once the technical portion is over, you'll usually have the opportunity to ask the interviewer anything you want. I usually have a few questions I ask every company ("what is the coolest thing you've worked on?", "what's something an intern has made that is still being used today?"), and then a few specific to that company. This is your opportunity to interview them and get to know the company better. It may also help to assert your value. After all, you are incredibly desired in the industry and it's their job to convince you just as much as it is yours to convince them. However, make sure you're respectful. Adobe won't be impressed by you asking about their security leak.

---

At the end of the day remember to enjoy the experience. Even if you don't land an internship, which a lot of people don't, it's great experience for when you apply to a full-time position and will give you a huge edge over people who didn't try. I won't say that internships aren't important, but it isn't the end of the world if you don't get one.

Good luck and don't worry! After awhile you'll have interviews mastered and they'll simply be part of your daily routine.

Friday, December 13, 2013

Tetrocity

The source code for this project can be accessed here. This post is largely a collection of loosely related thoughts I have about the development process. Go play the game first! Do it!

Not too long ago I was trudging through one of my online classes when the instructor mentioned something interesting. He brought up the idea of an expansion of Tetris: instead of game pieces (Tetriminoes) with 4 blocks… why not 5!? I was more intrigued that I had never thought of this before, considering the dozens of hours I wasted becoming mediocre at Tetris With Friends. I had made small command-line games before, but nothing really substantial and, you know, actually fun.

So, I set off. Like every OOP project anyone has ever embarked on, I was set on making it as clean, organized, encapsulated, modular, blah blah blah as possible. Surprisingly, I actually managed to succeed, for the most part. I spent a huge amount of time with Microsoft Word, planning my objects and their roles, game features and mechanics, before writing a single line of code.

It was a pretty huge revelation in my development as a programmer to see just how much this helped. It’s easy to get so excited about your ideas that you jump straight in to the code and make up everything as you go along. Almost every time I ever did that, though, it would turn messy pretty fast. Didn’t see that problem coming? Just add a method to this class… I’ll mark it private so nobody will see how badly it doesn’t belong there. That kind of thing adds up fast. I would at this point like to give a shout-out to any recruiter that may be reading this blog post. Please ignore this paragraph.

This necessity is one of the biggest disadvantages and advantages of OOP in general. In functional programming, it’s much easier to implement the functions you need as you go along. Keeping them organized is still important, but not nearly to the degree of OOP. Developing a system in a language like Java requires a lot more forethought. If you put in that initial effort, though, the payoff is massive.

Anyway, after a few weeks of playing around with the idea on and off, getting it sorted out in my head and on paper, I was ready to embark. First things first: more administration. I began by creating every single class that I had anticipated needing, and writing full documentation for each one. This is really just a continuation of the idea from before, but a hell of a lot more boring. I felt it was a lot like eating a salad. Immensely painful and soul rendering, but you walk away feeling better about yourself.

One of the biggest challenges I faced was designing the game in such a way that it would be easy to implement new features down the line. Despite the planning, I really didn’t know what would set my version of Tetris apart from the hordes of Tetris clones already out there.

I began by developing a small set of “fundamental truths” about my game’s mechanics. Really basic stuff that you would expect from any Tetris adaptation: pieces always fall south, the game is over when the board fills, etc. Everything else was completely variable. Tetrimino size? Needs to be potentially infinite. The number of Tetriminoes falling at once? Needs to be potentially infinite. Board size? Needs to be potentially infinite. You see where I’m going with this.

This is where I see a lot of code fail. It’s absolutely possible to write Tetris in a few hundred lines of code, with full GUI support and everything. However, this approach is too static in nature. The code fulfills a very specific purpose: nothing more, nothing less. Avoiding this is a critical aspect of good code. Good code is a brick in a building. You shouldn’t have to demolish the entire thing to add a new floor.

***

Enough preaching! I won’t explain the details of the code or anything. That would be tedious and you can see all of the code on the GitHub repo (it's pretty well documented. Start with the model package if you're interested in learning the game's structure). Instead, I’ll talk about some important things I learned, and then present some interesting problems I ran into, as well as how I solved them.

My first vision for Tetrocity was that every game would be highly customizable. I would begin by asking the player for information such as the range of Tetrimino lengths (i.e. the number of blocks that make up the piece), and the game would begin with those parameters. This was going to be a real selling point. “Play with huge pieces! Infinite possibilities!” I was going to make my game capable of producing infinite-length Tetrimino pieces anyway, so may as well give the option, right?

The first harsh realization I had was there was a huge difference between novelty and genuine entertainment. This is what it looks like when you ask for length 20 Tetriminoes. 


It’s definitely interesting to look at, but you certainly wouldn’t want to play a game like that. It would be impossible. In fact, even length 7 pieces are way too hard to use. Here’s my friend’s best attempt at playing with them (he could barely clear a single line).


If these lengths are impossible to play with, why would anybody want to? After the novelty of seeing them for the first time, there really isn’t much appeal. 

The more I thought about it, the more I began to realize that giving the player all of that control was not a good idea. How would they know what a realistic range of lengths are? Who wants to spend all of that time figuring things out before being able to enjoy the game? On top of that, my own experience with videogames lead me to realize that players would rather overcome a challenge set out for them than overcome one they set out for themselves. By taking control of the course of the game, I could much more easily control things like the difficulty curve, and high scores would have actual meaning. Tetrocity went from fully customizable to “Press start to play”.

I ended up limiting the range of Tetriminoes ever produced in a game to a minimum of 3 and a maximum of 6. It was somewhat disappointing that I wouldn’t be taking full advantage of my infinite length Tetrimino-producing object, but it was a necessary sacrifice of ego.

***

Tetriminoes are randomly constructed in a pretty straightforward way. You begin with an empty grid, place a single block in the center, and then randomly choose grid coordinates that share an edge with a block until you run out of blocks to place. This seems straightforward enough, but ended up posing a lot of problems. First off, this method does not produce every shape with equal probability.

To see this, let’s consider the original set of length-4 Tetriminoes being randomly constructed with this method. Is a line piece just a likely to be constructed as a square piece? Well, there’s only one way to construct a square piece. It looks the exact same regardless of how it’s rotated. A line piece, however, can be constructed two ways: vertically, or horizontally. These two orientations are produced via an entirely different set of coordinates, but any player would consider them equivalent. The more rotational symmetry a shape has, the less likely it is to be produced.

The first question we ask is: is this really a problem? Is the effect noticeable? As it turns out, not only is it noticeable, but it’s also somewhat desirable. In a very hand-wavy sense, the more rotational symmetry a piece has, the less likely we’ll be able to find a place for it, since you can’t rotate it to fit various openings. This is a trivial concern for length-4 pieces, but would be a huge issue for length-5 pieces. I would argue that the game would be way too hard to play with length-5 pieces were they all produced with equal probability.

In true hacker fashion, we’ve turned a bug into a feature! Except for one issue: line pieces have relatively low rotational symmetry. When playing the game, I found that I would go ridiculously long periods of time without ever seeing a line piece. As any player of Tetris knows, they’re critical. Since they have such special meaning, it was necessary to implement some way to increase the probability they would appear.

The way Tetris decides what pieces to give you is actually pretty cool. It begins with a set of all 7 length-4 pieces, and shuffles them randomly. It then feeds you pieces from that set. As such, we expect a line piece to appear once out of every 7.

To mimic this behavior in Tetrocity, I had to implement a probabilistic model, since piece shapes are not stored in software. I made the Tetrimino-production class return random shapes with a certain probability, and straight-line pieces otherwise. This way, we can control the expected number of straight-line pieces fairly easily.

***

An interesting bug I ran into with my Tetrimino-production class TetriminoFactory had to do with Java’s Random class. We’re all guilty of mentally blanking the “pseudo” in “pseudorandom” from time to time, but after the several hours of grueling debugging that resulted from that mindset, I probably won’t make that mistake again.

The bug presented itself as pretty easy to fix. I noticed it when testing TetriminoFacotry’s random shape generation. Regardless of what range of lengths I would give it, it would always give me length-4 pieces. Okay, so the method probably isn’t receiving the correct range information, right? Nope, that was fine. I managed to narrow it down to single call to my Random object’s nextInt() method. Absolutely everything up to that point was working as intended, and everything after it was not. The nextInt() method would return the same number every time. Definitely not random, although still technically pseudorandom I guess.

I isolated the relevant code and began testing, and could not replicate the problem. It seemed like magic. Every relevant parameter was recreated, yet the bug only occurred when the code existed in the Tetrimino-production class. I even tracked down the source code and learned the underlying algorithm in an attempt to figure out why it was occurring. No luck.

Eventually desperation set in and I began to just randomly tweak parameters in some vain hope of something happening. Surprisingly enough, it worked! Apparently, the bug only occurs when the requested range is a power of 2. That was not something I replicated in my isolated code. In my original test code, the range of Tetrimino lengths was 3 to 5. 5 – 3 = 2 = 21.

Why is there such an arbitrary shortcoming in Java’s Random class? I have no idea!
To this day I have no clue why this happens. Regardless of the seed you give it, Java’s random object will return the same value if the range is a power of 2 (it actually begins exhibiting random behavior again after the 15th or so call). Weird.

***

Another interesting challenge was making the program user friendly. Anybody who makes software in industry is well aware of the importance of this, but Tetrocity was the first time I've ever really had to take that into account. 

Tetrocity isn't a particularly complex or deep game. It isn't World of Warcraft, where things like complicated UIs are a justified necessity. Tetrocity is a relatively simple, 2D game. Probably even a mini-game by today's standards. As such, it was very important to convey the new features of the game in as simple a fashion as possible. 

This was pretty easy for the most part, thanks to the success of Tetris. Most people seemed to be aware of the rules and such, so I had to do very little work in explaining that aspect of it. Controls were also borrowed from Tetris With Friends, which makes it intuitive for any Facebook-savvy players. 

The biggest challenge was introducing the ability system. It was certainly new to most players, yet it needed to remain somewhat mysterious in order to motivate people to continue playing. Apart from a single line on the "Controls" welcoming screen, there wasn't even a good way to introduce the concept of abilities without shoving it in the user's face.

Pictures proved to be the best way to get around this. I found a set of free vector icons available here, and sifted through them to find the ones that best described an ability I wanted to implement. By sticking huge icons right off the side of the main grid, I wanted the player to be able to quickly glance at the sidebar, and understand what the ability did. 

I'm not sure I entirely succeeded in that regard. I've found that new players generally don't even notice when a new ability is unlocked, let alone what it does. The main game is simply too intense; your eyes are completely locked on the grid. After a couple of tries people begin to notice the abilities, but I wanted people to know it was there immediately. 

This was partly what motivated me to add sound effects, the majority of which I found here. That way, I could add a little sound that would play every time an ability became available, so that the player wouldn't have to take their eyes off the screen. Again, this was less successful than I had hoped for the reason. Players are just too focused on the game to notice the sound. 

This seemed to work fairly well, but at the end of the day I think a "How to Play" screen is really the best solution. I haven't implemented it yet, nor am I sure if I will, but it's definitely something to keep in mind when your game is too fast paced for the player to really "figure things out". 

*** 

Another important factor in making the game 'easy to use' was the fluidity of the controls. This was actually pretty interesting, because it was the first time that the behavior of my methods became fairly "hazy". I began by developing a very strict definition of what it means to move and rotate a piece. If it was found that these transformations could not occur, they wouldn't. Period. 

From a "contract" point of view everything was fine, but what I found is that the controls became extremely rigid. For example, if a line piece were flush with the right edge of the board and you tried to rotate it, nothing would happen. Logically, that rotation would cause the line piece to protrude off of the board. In fact, the line piece didn't even have to be flush. There could be several spaces in between the line piece and the edge of the board and the rotation would still fail. 

It simply didn't feel right. Again, the game is intense. It simply isn't realistic to expect the player to be that meticulous about every single rotation. When a rotation like that fails, it's incredibly frustrating and confusing. This is was motivated me to begin coding my controls to be "error tolerant". In this example, I made it so that when a failed rotation is detected, the game will automatically try to shift the piece over to the left, and check again. This way, when we encounter that same rotation failure from before, the line piece will be "pushed" left, and rotation will succeed.

Of course, you have to be incredibly careful about just how error tolerant the controls are. How far should you try shifting if left before giving up? Does it have to be the edge of the board; what about another piece? What if it gets shifted into another piece? Once you work out all of the kinks, it feels much better.

***


These are some of the things I learned while making Tetrocity. At the end of the day, I’m extremely proud of how it turned out. It’s the most substantial amount of code I’ve written personally from scratch. The game runs smoothly and is fun as hell. I should go back to studying for finals now, but I’ll probably edit this post as more things come to mind. In the mean time feel free to give the game a go. My high score is about 300000; see if you can beat it!