Now that 2019 is almost here, I’ve been reflecting on my personal & professional journey as a self taught programmer so far. Here’s my story of going from a media arts degree and no job to working fulltime remotely.
2018 marks my first year being a professional programmer. That is, actually earning income from it. In late 2016/early 2017 I had been looking for work but I hadn’t done it correctly. My largest mistake was not networking.
I was living in Chicago at that time but I was still making the vast majority of my applications online, through sites like Indeed or Hacker News’ monthly Who’s Hiring? threads. As a Media Arts major with no formal software experience, it’s not hard to see why it was a bit difficult to apply to backend developer jobs—or rather, just non-web/frontend developer jobs. I suppose I could have found a job doing that much faster, but I loath it. ¯_(ツ)_/¯
The other two mistakes I made were not hanging around in the right circles and focusing on a specific programming language when job hunting. I attended ChiPy [Chicago Python]’s monthly meetups—which I do recommend—but I was looking for ruby jobs. So the Python jobs recruiter in that group wasn’t able to help me.. I should have at least attended meetups that focused around ruby.
As I’ve come to realize, I should’ve just applied to any entry-level
roles in Backend dev, whether it be in
c#, etc. It’s
better obviously to have experience in it already, but I learned so
much about ruby on rails in my first job that I might as well have
known nothing. My personal experience merely gave me a headstart.
However, I worked primarily alone in my first job—not knowing much about
rails probably wouldn’t have worked out well.
I did eventually find a ruby on rails job, but now I’m working on a c# asp.net web api project. My general skills transferred; all I had to do was get up to speed on the idiosyncrasies of this particular framework and ecosystem. (And I love it. Statically typed languages for life!)
My first programming job
I found my first job through the Open Source South Carolina meetup. I attended a session and Todd Lewis (the organizer) mentioned that he had a few internships he knew about. I talked to him afterwards and got the email of someone who needed a ruby on rails guy to help him out with some of his side gigs. Thus, I agreed to work part-time (about 10-15 hours/week) at $10/hour.
Although the project’s backend was ruby on rails, I also had to learn Elm for interacting with the frontend. Lesson learned: You always need to be able to expand your skillset. In the end I’m really glad I learned Elm—if I work on a frontend again, I’ll likely use that.
This went on for about 2.5 to 3 months. I was a sub-contractor for a side project my employer was working on and he billed my hours to his clients. I was eventually told the clients were putting a hold on the project for a while, so there wasn’t anything for me to do. This worked out as I’d started the application process with Gitlab as a rails backend developer.
Applying to Gitlab
I applied for Gitlab’s backend-developer role, at $55k I believe. The amount was whatever their calculator gave me for South Carolina + no experience. For what it’s worth I’m not a huge fan of this concept in retrospect. Part of a job is negotiating for pay—actually being ``transparent'' would be just an open spreadsheet of employee salaries, not taking away negotiating power from prospective applicants. That said, it is at least standardized. I mean, I still applied, so I can’t criticize much, but the rest looked great aside from not providing benefits in Korea—where I wanted to live.
The interview process was long. The process involved scheduling two behavioral interviews before the coding interview, and each one was weeks out due to their busy schedule. I made it through those pretty easily. Then I got to the actual coding: first a 60 minute interview and then I had to work completing a merge request. I think the interview itself went alright; aside from Zoom crashing twice on Arch Linux, I was able to ask a lot of questions about Gitlab’s overall code structure and how some things tie together. Side note: Asking questions in interviews is extremely important. It should never be a one-sided thing.
So I spent the next week working on implementing this feature and asking them questions. Due to the distributed nature of Gitlab sometimes my questions took a while to get answered. A large mistake I made was not including tests in my submission initially. The process involves iterating on the merge request two times based on their feedback. At the end they told me they wanted a candidate where they didn’t have to point out such things like including tests.
I’m okay with it. I definitely read a lot more about the things I had worked on in that merge request. Sometimes you’re just not what a company is looking for, and all I could do was learn from the experience.
Luckily, at the same time I received an offer from someone else!
My first real programming job
About a month before applying to gitlab, I had met my current employer, Chad, at All Things Open Columbia—another conference organized by Todd. After the conference I mingled with some people at the local bar, met Chad, and mentioned that I was familiar with ruby. He said that he might need a ruby guy for a project in the future, and then we parted ways.
Well, he did in fact need a ruby guy later on. So we discussed it and I became employed at Open Source Systems to work on an existing project headed by a doctor at MUSC. It had two other part-time developers but I was practically working alone for the majority of the time. After about 5 months the funding for the contract was temporarily up so I got assigned to a new C# rest api project with a company based in Charleston. And that’s pretty much where I am now—helping migrate a legacy codebase to a leaner, modern rest api implementation.
This company is 100% remote! I live in Columbia, SC, my boss is in Charleston, and we have other employees in various places. Sometimes I really can’t believe it—I’m earning money and getting valuable experience while not having to commute or work typical hours. In fact, I’ll be staying in Korea, Japan, and Taiwan for months at a time starting next year. :-)
And it’s all from networking. At All Things Open 2018 in Raleigh, NC I met an IBM employee who I can contact if I ever want to for IBM in Korea. I don’t plan to—working remotely is just incredible—but it just shows you just how good these events are for finding work. If I had stayed for drinks on the second day I likely would’ve found other opportunities.
Things I learned
For a good month and a half or so I took a rails codebase from zero tests to a fairly comprehensive testing pipeline. I was just shocked initially that a program for calculating medical simulation data and displaying it had zero tests. There were more than a few instances where the reports simply had incorrect data due to some math or datetime bugs…
The very first thing I did was set up an automated Semaphore CI test process that ran on every commit on every branch. Setting things up on there is very straightforward for ruby apps. Then I learned a lot about the FactoryBot, RuboCop, and Brakeman libraries. I initially tried to model everything with FactoryBot but our data model was a tad convoluted and it made the factorybot setup very brittle to work with. So I ended up reverting back to a custom rails’ Fixtures solution for a bulk of the tests, which also made the overall testing time way faster.
Sometimes a standard framework (like FactoryBot) may not suit your particular testing style or needs. Don’t use things just because it’s a style or trend.
Organization / Separation of Concerns
This is more particular to traditional MVC-architecture applications,
particularly ruby on rails. The project I took on had huge swaths of
code & extraneous logic inside its
controllers. I had to spend a lot
of time refactoring and moving that code into a relevant
command file, but it was worth it as:
the controller/view logic became significantly more readable.
later on when I rendered via PDF & XLSX in addition to HTML, already calling the logic through `service`s saved a huge amount of time. I would’ve either had to copy the logic or heavily refactor anyway.
Learning outside of your current skillset
The reality of working on real projects is that you invariably will have to learn things outside of your wheelhouse. When I first learned rails I had to learn SQL shortly after because you need to do things manually sometimes. I had to learn how to generate PDFs, and so on. As you implement different things you should always be growing.
Sometimes you have to switch languages and frameworks entirely, which is perfectly fine. Getting acclimated to the language’s syntax, ecosystem, etc. can suck but usually it’s a very brief period. However don’t switch just for the sake of it—have a good reason. No, it being discussed around the watercooler and on Hacker News is not a good reason to switch.
Areas of Growth
Ruby/Ruby on Rails
more frontend familiarity (Vue.js / Elm)
PDF & XLSX generation
code organization via `Service`s/`Command`s, etc
more quickly getting up to speed on large codebases (like gitlab’s)
writing CLI tools with option flags parsing via Clap
better error handling
C# ASP.NET Web API 2.1 / MS SqlServer
MVC layout / idiosyncracies
SQL Server dialect for queries, and more complicated sql queries in general
working with decade+ old stored procedures
Implemented a Lexer and Parser in Crystal lang to recursively evaluate client commands
Goals for 2019
My most present goal is to learn Common Lisp. I enjoyed Clojure but I hate its gibberish error messages. CL tells me exactly what I did wrong most of the time.
For my job it looks like I’ll continue to learn C# ASP.NET and SQL Server, but my side projects will be Rust or Crystal, with Postgres. Perhaps my real goal should be to actually finish more side projects instead of getting distracted…
I just want to keep learning and growing overall. I don’t know if I’ll actually develop in Common Lisp, but I do know it’ll give me a new perspective in programming. I’m very excited to see what 2019 offers in terms of safe, performant languages.