Life as a stable|kernel intern
May 7, 2015
Before I started as s stable|kernel intern, I considered myself to be a “good” programmer.
Over the course of a couple of years, I harnessed my ingenuity and persistence to teach myself Android development and database management. I watched countless hours of video tutorials, read numerous development blogs and paid my dues per se on Stack Overflow. This eventually led to me publishing two apps on Google Play.
Despite the satisfaction of having my work published, I could not help but question the quality of my work. My code was reliable, but was it robust? I had no way to gauge my coding ability and honestly, it was a bit scary. Did I truly have a firm grasp of the Android platform? Was I progressing or was I just developing bad habits? Was I really a “good” programmer? These doubts were further exacerbated whenever I would see a cool feature in an app and have absolutely no clue how it was implemented programmatically. I needed guidance. So when I stumbled across stable|kernel’s blog and saw that they were local, I didn’t hesitate to knock on their door with my resume in hand.
It’s the first day of my internship and Joe Conway, the founder of stable|kernel, dropped a bomb on me. He hands me a MacBook Pro along with a copy of his bestselling book and says, “I know you’re an Android developer, but we have a few iOS projects coming up, so go through the chapters in the book and bring yourself up to speed”. Wow, not only do I have to learn iOS quick, fast and in a hurry, but I also have to learn how to use an Apple computer, as I have never owned a Mac before. Talk about a learning curve! It just got real at the stable|kernel offices!
Later on, Rondale (the other stable|kernel intern) and I received an overview of the stable|kernel process. We were introduced to the concept of a living App Map which is built using tools such as OmniGraffle, Invision and Proto.io. App Maps are better than storyboards and wireframes because they are dynamic. We also learned how stable|kernel is pushing the envelope by prototyping apps for clients using tools such as Flinto, Pixate, Quartz and Origami. When designers prototype and test their designs instead of just drawing them, developers don’t waste time making apps that are not intuitive. Later on, our project manager Charlie gave me a crash course on the stable/kernel workflow using Pivotal Tracker and Slack. Lastly, Joe spoke about source control using gitHub. It’s the end of the first day and my head is spinning.
Joe noticed me pecking and clicking away as I get accustomed to working on a Mac, while solving the iPhone challenges in the book. He said, “Good programmers use a mouse, great programmers use hot-keys”. Joe then gives me a brief demonstration of how much more effective it is to use hot-keys as opposed to the mouse and finishes by handing me a sheet of hot-keys, imploring me to internalize them.
Today, Joe taught me computer science 101. First, he explained a little bit of binary code and then he expounded on how all applications in their most basic form are just code text, stack and heap. The conversation was invaluable, especially considering that I have no formal education in computer science. It’s one thing to have a grasp of a SDK, but it is a completely different level of understanding when you can conceptualize how the SDK is just an abstraction that is underpinned by the code text, stack and heap, which itself is an abstraction underpinned by 1s and 0s. I now understand what is actually happening when I get that dreaded NullPointerException.
Rondale and I finally finished the Challenges in the book and were informed that we must develop a dart game for iOS. What makes this project particularly interesting is that we have to use Core Data for statistical analysis and persistence. Dart games at the stable|kernel offices are more intense than SEC football, so this is a pretty big task! This project will help determine bragging rights in the office.
My colleague Jesse, a developer here at stable/kernel, invited me to attend the monthly Atlanta Android developers Meetup group. The presenter’s lecture was particularly timely for me, as he discussed Git Flow. Earlier in the day, I encountered merge issues when trying to commit my work, so being introduced to git commands besides the usual push, pull, commit and checkout was extremely helpful. The open spaces portion of the meeting was even more rewarding, as it gave me the opportunity to learn the approaches and solutions of erudite programmers in areas such as ORM and Image caching. I would definitely recommend that anyone who is serious about mastering a craft such as software attend a meeting like this.
I made the mistake of assuming that Core Data was structured and functions the same as SQLite. I could have saved myself much frustration and time had I not made this assumption. iOS handles persistent data completely different than Android. I will definitely be mindful to never again assume that something on iOS is the same as Android. In my fit of frustration, Ross, our Director of Android, caught a glimpse of my monitor and suggested that I install Zsh and Scm-Breeze to help improve my git interface and workflow. It definitely makes a difference having a Terminal that is more readable and hot-keys to navigate git. My Terminal is almost now “GUI-like”.
Joe made sure to emphasize to me and Rondale the importance of naming methods so that they read like sentences. As an application grows and becomes more complex, it’s beneficial to be able to read a method name and know exactly what is being executed. He also suggested that we keep our method names consistent, particularly when writing delegate methods. Delegate methods should all have similar nomenclature based on whatever object possesses the delegate. Also, the delegate should make no assumptions about what class or object is implementing its delegate methods. Later, Joe cautioned us to not use Stack Overflow and told us that our time searching for programming solutions would be better spent combing through the iOS documentation. Running to Stack Overflow at the first sign of trouble is a bad habit that I am working hard to break. Whenever I feel tempted to go there, I just remember what my colleague Eric said: “Don’t become a Cargo cult programmer, Bryan.” Eric’s advice is keeping me on the path of Stack Overflow sobriety.
Rondale and I encountered an interesting problem while keeping track of UICollectionView cells. Joe used this as an opportunity to teach us a technique on how to track views after ViewWillAppear is called. He suggested that when building custom methods for UICollectionViews and UITableViews, pass the address of the variable instead of the value of the variable. De-referencing the variable changes the value at the particular address instead of the pointer to the variable. This is a “passing-by-reference” technique to get around the constraints of Obj-C since the language doesn’t allow tuples. Today’s lesson definitely elucidated Joe’s earlier computer science 101 discussions and I am beginning to understand why things are happening on a conceptual level.
Today, I gained a true appreciation for the concept of the Model-View-Controller design pattern. Before interning at stable|kernel, I was vaguely aware of the benefits of strictly adhering to MVC when developing applications but considered implementing model objects an extra unnecessary step. Now, I understand that MVC is a design pattern that makes Object Oriented Programming plausible and once one has a firm grasp of OOP they can begin to do some serious functional programming.
Currently, I’m breaking my bad habit of using view states to drive the application. Views should be agnostic, meaning that they should just be implemented to represent the data of the model object. As for model objects, I have learned to initialize them in my init method and structure my code in such a manner as to only move model data into view once. Today, I also learned that optimizing my code should not be my first priority. Instead, I should focus on writing code that is more functional and readable, so it becomes reusable.
I’m still internalizing my newly adopted paradigm of MVC. Refactoring of my old code has made me realize how often I wrote methods and classes that required the view state to be tracked. Coding is so much easier when you write functional methods and classes that simply take inputs and return outputs, making the method or class behavioral.
As I write more code with Joe’s guidance, it’s becoming more evident that ViewControllers essentially just handle callbacks. Also, I’ve learned that my Store Class, which is used to access external data from the web or filesystem, should only be accessed from the ViewController. After receiving data from the Store Class, the data should be passed along to the model graph. Today, I had my first opportunity to unit test the project Rondale and I are developing. Seeing the application logic work without using a user interface allows me to see yet another benefit of using design patterns in application architecture. Logically-sound model objects lead to seamless unit testing.
Auto-Layout is the devil! Who would have ever imagined that it would take an entire day to figure out how to embed a Scrollview in a layout for iOS? Android definitely is the better platform for developing user-interfaces, because Apple made their Interface Builder extremely complicated for no reason.
Joe gave me some very helpful pointers how to construct a view hierarchy in Auto-Layout that accommodates ScrollView. First, establish a GuideView in the SuperView that will act as a point of reference for the view containing the content in the ScrollView. Pin this view to the edge of the SuperView on all sides. Second, Add the ScrollView to the SuperView as a sibling of the GuideView and pin it to the edge of the SuperView on all sides. Lastly, embed a ContentView within the ScrollView. Add a constraint that set the height and width of this view equal to that of the GuideView. Next, pin this view on all sides to the edge of the ScrollView. From this point, the developer has the option of embedding another view within the ContentView, which accommodates the dimensions of the smallest iPhone screen and doesn’t stretch to remain aesthetically pleasing on the iPad. To accomplish this, set this view’s width to 320, set the height equal to ContentView and align it to center along the x and y axes.
Today, Ross let me get my feet wet working on an Android project for an actual client. First, he brought me up on a couple of libraries and tools he uses in the project: RetroLambda and RxJava. RetroLambda allows developers to use Java 8 syntax in Android development. Having the ability to use lambdas allows programmers to do in one line of code what used to take seven. This makes it easier to write code in a more declarative style, which makes it more functional. RxJava allows for parallelism in applications by enabling the ability to run multiple threads in thread pools.
I sat in on a client meeting and witnessed firsthand the importance having an App Map as a living document. As the client ran through the list of changes he wanted to see in the app, our Lead Designer Matt applied those changes to the App Map in real-time. This not only allowed the client to see his vision take shape but also ensured that developers were on the same page as the client. This further convinced me that the App Map is the single most important document or tool in the software development process.
In just 2 months at stable|kernel, I have acquired what feels like two years worth of knowledge and insight. I can’t wait to see what the future holds.