“RKODE Boot Camp”

If you’re in tech and you have friends outside our industry, you are probably regularly asked some flavor of the question, “how do I do what you do?”, which is usually a question regarding high pay, freedom of work location, what I would call an “adult” level of trust from your colleagues and superiors, and flexibility in how you get the work done, among other benefits. There is no magic to working in tech; if you want to use your brain without needing an advanced degree, it’s a great way to get paid and survive, and maybe even buy a house and retire some day. For many it is a position of privilege that enables getting there – for me that was absolutely the case, which is a discussion better in person than on a public blog post. Furthermore, the way to “get a tech job” evolves all the time – the path I took would not look the same today.

Recently my partner was asking more seriously about what a path like this could look like, and asked somewhat rhetorically, “Should I just go to a code school?” And I have pretty strong negative feelings on that. The ONE code school that I used to think was pretty decent has also really disappointed me in the last few years. In my opinion, the folks that will get a job and stay in industry for more than a year or two would have done so without the expense and unaccredited/ever-changing program of a code school. Saliently, you cannot earn as an instructor for a boot camp/code school (interchangeably in this blog) what you can earn in industry. I can think of a dozen people who did these programs whose instructors suddenly dropped in the middle of a term, because they were doing the job while applying to software roles. I used to tell folks to check if the instructors had themselves graduated from the code school they were teaching at, which tells me whether or not the code school is teaching you to perform this program, or actually learn practices for industry.

So! What to do? I’m self-taught, with one code class that I took at the beginning of my journey in 2013. After the course was over, a woman fellow student recommended PyLadies, and I made the decision to go every Saturday and work on my projects and publish blog posts on what I was learning every week, and I did that for a year while I was finishing my degree in French and minor in Mathematics. That led to a weird little internship, which then led to 18mo in Support Engineering at a server config management company, which then, roundaboutedly, led to five years at my old company and three years in my current company as an operations engineer/devops engineer/site reliability engineer (these terms evolve), a space I’ve now inhabited since 2016 over a few roles. So I do think there is real possibility in a background, but consistent, learning toward a tech role, but I find myself frustrated by just how much money that seems to cost. With that in mind, I started punching up what I think would give you a base on which to seek out and competently interview for for entry level technical roles – junior software engineer, technical support engineer (emphasis on technical), IT desk/service, and more.

Language – pick ONE!

Lots to choose from but below is the list I think one could pick from and stick with – don’t bounce around too much once you’ve chosen. It’s important to learn deeply before casting your net too widely. Once you can read one language and make out its control flow reliably, you really can read most any language, and starting to work in a different language is really not too bad. You will find yourself forever comparing a new language’s paradigm to what you already know, so you want to make your first mental model strong. I started with Python and have seen it used from frontend to backend to personal scripting to simple data management, I have learned some C/C++ and boy oh boy can you get paid big bucks for being able to navigate its ancient and hallowed nooks and crannies well, JavaScript and Typescript are foundational and critical for web development, and Java is just ubiquitous. Describing these languages beyond this very brief sketch is outside the scope of this already monster-sized blog post. If there is another language that you are strongly considering that is not on this list, go for it! Learn it deeply. I think the program I’ve developed could very much be applied to many other languages as well, I just think that the five I’ve listed are terrific ones for beginners.

JavaScript, Typescript, C++, Java, Python

Who is this for?

I’m thinking of the adult professionals who can enjoy reading for its own sake and who are motivated to spend a couple hours a week – maybe more if you get really into something. Have you really enjoyed figuring out some piece of Excel automation? Have you gotten really into managing your own workflow, or improved upon/created effective, repeatable, teachable systems for getting some piece of work done? Have you, on your own, decided to pick up and complete a non-fiction book without external pressure? Do you enjoy engaging people on complex topics? If the answer to a couple of these is yes, I think you’d probably do well in a program like this and in this line of work, such as that can be hundreds of kinds of roles.

You’ll need a computer. You don’t need anything fancy, genuinely. A mac is probably best, but you can find used ones between 3-8 years old that will still work for a while, but a windows computer will work fine too. With Windows 10, you can use the Windows Subsystem for Linux 2, or WSL 2 for a real Linux command line. Personally I have not yet stumped my WSL 2 install with anything I’ve tried to do – python, bash, docker, rust, etc. If you would like to pursue a Powershell and native Windows based programming career, this isn’t really the blog for you, and I don’t think I’m the person to advise you on it, but godspeed!

The Program

Finally we come to the program itself that I jotted down one evening about a week ago, and keep chewing on as what I think could really get you a job in 6-9 months, for very little money – a fraction of a fraction of the cost of a code school. And if you get to the end (spoiler: the last one is “take a class at your community college”) and have decided it’s not for you, the money you’ll be out is the cost of a few books, NOT $30,000 or whatever they’re trying to charge these days.

  1. Join the main language’s slack or discord. Join the beginners channel, and pick five other channels to follow and keep up with. Make one of them social, and join conversation a couple times a week. If the channels aren’t active, pick new ones. Come up with a technical question to ask at least once a week in your learnings. Try to answer other newbie questions. This will be part of your learning experience for the rest of this program.
  2. Optional: a codecademy (or comparable free) class on one of the recommended languages
  3. One beginning programming book with exercises
  4. 3-5 videos and exercises on Git and version control
  5. PROJECT: Spend two weeks building something with what you learned. Feel free to liberally crib from the book you selected in step 3!
  6. One beginning HTML and CSS book with exercises 
  7. PROJECT: Spend two weeks building a local website with just html/css. Cribbing rules apply.
  8. One beginning systems or networking or ops or AWS book (not azure and not gcp)
  9. Optional but highly recommended: bash and Linux command line basics
  10. The Phoenix Project book
  11. Forge Your Future with Open Source book
  12. A second and more specialized programming book which contains exercises in the same language you chose above
  13. PROJECT: Spend two to three weeks building a project based on the specialized book you read.
  14. Workshop a larger idea* for a project, which will require your language of choice and html/css. Find a collaborator from your slack. Work on it for six weeks. Scoping this can be hard, but your new colleagues and your collaborator can work on this with you.  *If your language is c++, skip the html/css aspect.
  15. A community college course in your chosen language
  16. Stay active in the slack, start building a resume of projects with old jobs relegated to 1-2 lines each.

“But why this and not that?”

There are some pretty opinionated recommendations in the above list! My intention is not to offend but to offer my professional perspective. I really think you can throw a dart and find a perfectly good book to learn with, and as you develop and make connections with people, you’ll find the books you want to read on these topics. They can’t DRM you out of your own physical book, either. If you prefer e-reading or audiobooks (probably a little harder for hands-on computer learning but not to be discounted and plenty powerful still!), please feel free. Personally, I like to have the paper book, and find it’s harder to ignore than a PDF in yet another browser tab, competing for my attention with social media and whatever else I’m looking at at the moment. This isn’t a program I am administering, it is a set of guidelines I am recommending.

I feel that Git is something that is best suited to personal instruction, so instead of videos, you could ask a friend in your new slack for an intro if that is appropriate, or honestly if you’ve read this far and you’re still interested, I will try to make time for this for you, the reader!

If you’re going to learn a cloud hosting system, just learn AWS. GCP and Azure exist, but the ideas are the same so using a different one after learning a bit about AWS is not too big a lift. AWS is used all over and defined the game. Just be careful with the free tier if/when you start making infrastructure on there.

I think that this curriculum is missing an introduction to databases, and I really welcome your feedback on where that would fit in this setup.

The Phoenix Project and Forge Your Future might seem like odd items out in this list. However, TPP is a business of technology book that is well written and exciting and ~fictionalized, and the insights it offers are innumerable and years later, I find myself thinking about it and recommending it. Forge Your Future with Open Source is a how-to for getting involved with Open Source, which is a common but challenging recommendation for newbies, and this book explains and demystifies – and justifies! – how and why to get involved at this level.

Don’t sleep on the slack. Seriously, do not proceed without step 1! Join the language slack, get involved, get to know people, make it part of your community and your life and this program. You will not get a job if you don’t make friends in this network of people. Folks hire their friends. If you’re a beginner, you simply will not get a job over someone else if you are a total unknown. Once you have the resume, this will be less (or differently) important, but you probably don’t yet, so it’s time to add to the rich community of this language with your awesomeness! And you’ll be adding as much as you are receiving! Look for other questions to answer, ways to help, volunteer opportunities, and the “payoff” in lifetime connections and strength of networking will be utterly invaluable.

Thanks for reading! Please comment and let me know what you think! You can also email me at bootcamp at rkode dot com if you would prefer.

Mongo migration

For the past few months I’ve been at a terrific job, doing devops at a small SaaS company. Real quick, SaaS means “Software as a Service” & refers to companies that have a webapp that they either sell access to and/or set up a version of for their customers. There are a lot of challenges with doing devops for a company like this, trying to find the balance between the heavyweight solutions and the latest and greatest to find what’s right for us, all the while (personally speaking) doing a LOT of learning on the topic. That’s not to say that heavyweight versus the latest&greatest are opposed; there are a few more weights on that spinning disk, not the least of which is “what we were doing before was …”.

So what I’ve been working on for the last few weeks, somewhere between the old solution & the new hotness, has been a Mongo problem. We deal in data that must be scrubbed before we analyze it. So the way that works, is that the host captures data, then scrubs ALL data there, and then sends it on to our long-term storage database, and then all local data on that host is removed after a couple days. What we’ll do with all of this in five, ten years will hopefully be the subject of another post, but for now we are only dealing with about 30GB of data in the long-term storage DB, collected over the last couple years. Let’s call that “Storeo,” and the hosts that they come from “partner databases,” which is true enough.

We’ve developed a couple of schemas for Storeo, and we only upgrade our partners from one to the next with code releases. So we have a couple old versions of Storeo kicking around. The next piece of this story is that we have an analytics dashboard set up for each partner, which pulls from Storeo, based on a domain field in the data we get from each partner. There’s one for each version of Storeo that they (and we) have to refer to, which means multiple dashboards just to get all the info! So that’s foolish, yeah? As a result, a previous engineer wrote a Mongo migration script to migrate all data from version 1 to 2, and then from version 2 to 3, the current version. So there are two steps to this – first, to migrate all the legacy data up to the current version so everything can be analyzed in the same way, and second, to do this regularly so even if partners are using older versions, we roll that data up so there is ONE source of truth for all their data.

As happens occasionally, no one can quite remember how I got this project, but it’s been a ride. Mostly good, occasionally “how the hell does Mongo even work?”. Some of the problems I’ve gone through have been of a Mongo nature, some of them of a sysadmin nature, some of them just basic DBA. Many of these steps might make you scream, but I’m cataloguing them because I want to try to get down what all I’ve done and learned. When you are self-taught, your education comes in fits and starts and in no particular, and in sometimes infuriating (out of) order. So I’m going to do my best to show you all the things I did wrong, too.

Problem 1 – Where to Test

I wanted to test the migration locally, not on the production Storeo server, which continues to receive data from all our partner database. First, I fired up the mongodump docs and tried that. Well, I nearly immediately ran out of room, and deleted that dump/ directory with those contents. When I looked around with a df -h /, a command which shows you the disk file size on root, human-readable, the output was that there were only a couple gigs left. Well, I knew that dumping a 15GB database wasn’t going to work locally. So I investigated a lot of other options, like sending the mongodump to another server (technically possible), SSHing into the server but sending all dumped data to my local machine with plenty of space on it. This probably took a couple days of investigation between other tasks.

None of this really panned out (but I still think it should have), and my boss let me know that there’s a 300GB volume attached to Storeo, and I said, wait, but I didn’t see that, I looked for something like that, and they gently let me know not to give df any arguments in order to see all disks mounted on a server. With that, a df -h showed me the 300GB volume, mounted on /var/lib! Excellent. On a practical note, it’s extremely sensible to have all the data for your application stored on a volume rather than on some enormously provisioned server. When you use AWS, one volume is much the same as the next, so putting databases on their own volumes is pretty sensible. Keep your basic server’s disk very bare bones, put more complex stuff on modular disks that you can move around if you need.

So with that!! I made a directory for myself there to separate from the production stuff, confirmed that mongodump/mongorestore do NOT interrupt read/write operations, and made mongodumps of versions 1, 2 and 3. This took.. maybe an hour. Then, because they were still quite large (Mongo is very jealous of disk space), I tarballed & gzipped them to reduce them down to half a gig or so. We use magic-wormhole all the time at work (available with a quick pip install magic-wormhole [assuming you have Python and pip installed {but it doesn’t have to be just a Python thing, just like I use ag and that’s a super Perl-y tool}]) so I sent these tarballs to my local machine, untarred/ungzipped, and mongorestored to the versions of Storeo 1, 2, & 3 that I have locally to run our app on my own machine. This probably, with carefulness and lots of reading, took another couple hours. At this point we’re probably a week in.

Problem 2 – How to Test

At this point, I finally started testing the migration itself since everything was a safe copy and totally destructible. Also I retained the tarballs in case I ended up wanting to drop the database or fiddle with it in some unrecoverable way. I took a count of the documents being migrated, and of the space taken up by each DB (which was different than on prod – I thought until this week that those sizes should be constant from prod-mongodump-tarball-mongorestore, but that’s not true – apparently most databases are wiggly with their sizing). The migration script is a javascript script (how do you even say that) that you feed into mongo like so mongo migration1-to-2.js, within which you define dbSource and dbTarget. The source, in this case, is version 1 of Storeo, and the target is version 2. Each of these is a distinct database managed by Mongo. With great trepidation, I did iiiit. Ok, I’ve left a piece out. I, um, didn’t know how to run JS. Googling said “oh just give the path to the browser!” so I did and, uh – that didn’t work. You may be saying “Duh.” Look, I’ve never done any front-end at all, and have never touched javascript outside that Codecademy series I did on here a couple years back. With my tail between my legs I asked my boss again, & was told about the above, just mongo filename.js.

The script took three hours!! Gah! So I ran the next one, which took SEVEN (since it contained everything from the first one, too), and regular attention to the ssh session so I didn’t lose the process (don’t worry, linux-loving friends, I’ll get there, just keep reading). These two migrations took two business days. At this point, we started talking to the team who manages the data analysis dashboards for our partners to talk about some of the complexities. Because a) this isn’t a tool from Mongo, there are no public docs on it and b) you can only test Storeo performance after the data has been scrubbed and sent, even locally, we decided to set up a few demo servers to point to test versions of the database.

Remember the volume attached to Storeo on production? Whoo! I logged onto Storeo and learned a ton more about mongodump & mongorestore, and made teststoreo1, teststoreo2, and teststoreo3, exact mongodump/restore copies of versions 1, 2 & 3 of Storeo. Their sizes, again, were different, but we’ve learned that that’s ok! Mongo has a lot of guarantees, space management isn’t one of them, so pack extra disk and we’ll be fine. So because this took a lot of googling and careful testing, because the last thing I wanted to do was mongorestore back into the place I’d mongodumped from – at the time I wasn’t sure if mongorestore overwrites the disk entirely, and wanted to be cautious versus potential lost data. So, make the directory, mongdump into it while specifying the database. Then restore into a new database (with the same name as the directory you’ve just made – this isn’t mandatory but made it easier to trace) while feeding it the path where the mongodump lives.

mkdir teststoreo1 # make the directory
mongodump -d storeo1 teststoreo1/ # dump the database with the name storeo1 into the dir we just made 
... # this takes some time, depending of course on the size
mongorestore -d teststoreo1 teststoreo1/storeo1 # there could be a dump/ in front of this end path

So after doing this for the other two Storeo databases as well, a show dbs command in the Mongo shell outputs all three production Storeos, as well as all three test Storeos. This meant we were in a good place to do some final testing. There were a few more meetings assessing risk and the complexity of all the pieces of our infrastructure that touch Storeo, how you do. Because the function of Storeo is to continually take in stripped data, I had to ensure that we weren’t going to lose information being sent during the migration. Because it’s not an officially supported tool but instead something that we wrote in-house, and I hadn’t been able to find a tool that moves data from one mongo DB to another, it’s hard to know what will and won’t impact production, so I set up one of our demo servers to send its stripped data to teststoreo1, and then kicked off the migration from teststoreo1 to teststoreo2 to make sure there was no data loss. On that demo server, while the migration was migratin’, I made a bunch of new dummy data that I’d be able to trace back to this demo server. A few hours later, when the 1-to-2 migration was complete, sure enough there were a handful of documents in teststoreo1 that were new – they’d been held & NOT sent! With this, I was very happy with the migration script.

So I kicked off the following script with mongo migrate1-2.js, quit the process with ctrl-z, and put it in the background (after identifying it as job 1) with bg %1, so it wouldn’t be interrupted by my leaving the session (see?)..

'use strict';

var dbSource = connect("localhost/storeo1");
var dbTarget = connect("localhost/storeo2");

// The migration process could take so long that new documents may be created
// while the script is still running. We will move only the ones created
// before the start of the process
var now = new ISODate();

dbSource.collection_1.find().forEach(function(elem){
    elem.schemaVersion = 2; // this means each element is given the NEW schema version
    dbTarget.collection_1.insert(elem);
});

dbSource.collection_2.find({createTime: {$lt: now}}).forEach(function(elem){
    elem.schemaVersion = 2;
    dbTarget.collection_2.insert(elem);
});

dbSource.collection_3.find({timestamp: {$lt: now}}).forEach(function(elem){
    elem.schemaVersion = 2;
    dbTarget.collection_3.insert(elem);
});


dbSource.collection_1.remove({}); // this collection did not have a timestamp
dbSource.collection_2.remove({createTime: {$lt: now}});
dbSource.collection_3.remove({timestamp: {$lt: now}});

The second script was the same but for the definitions of dbSource and dbTarget to storeo2 and storeo3, respectively. As with the testing, the first one took about three hours, the second, seven. With each one, I kicked it off, then put it in the background, then checked on it… later. Because it’d been backgrounded (that’s a verb, sure), it wasn’t quiiiiite possible to tell when it was done. That could be fixed with some kind of output at the end of the script, but that’s not how I did it!

Then I set up a lil cron job there at the end to regularly move data from 1 to 2, and once that had run for the first time, then I set up the second cron job to move it from 2 to 3.

Who wants to talk about Mongo????????

Javascript cribsheetery

So to declare either variables OR functions (and I assume, later, objects? unless it turns out they’re the same – they might be the same), it begins with var variableName = and if it’s a simple variable, it behaves predictably, and moves on to var variableName = (5 * 2). If it’s a function, this entire lovely curly brace structure needs to be set up:

var functionName = function (parameter) {
    console.log(parameter * 2);
};

and then to call:

functionName(5)

where 5 is the parameter of the function functionName.

Ok. Rock and roll. Movin’.

Javascript first thoughts, mackatoots, & tutorialino

Hello again! I have been working and working and working, lately, and I have a few things up my sleeve!

First, my company, The Open Bastion, is working on tutorials in Python. Get in touch if you’d like to create with us! Note: paying gig 🙂

Next, though I know some Python, it seems that I need to keep going, so I am learning Javascript, now. Exciting! Something altogether new! So far, it seems like a friendyfriendly C analogue, based on the 50-odd pages of a C++ book I read back in the day, which makes web site and app creation a BREEZE. I know complications will come – I feel like I hear more complaints about Javascript than any other language, right now, but as with all new languages, I’m really enjoying learning the syntax. I’m doing the Codecademy interactive tutorial and it’s adorable and fast fast fast, so I feel like I am getting a lot done and learning learning! Note to self (and to youuuu!) to research later – why are semicolons sometimes required at the ends of lines & sometimes not? I wonder – is it more than just good style? With Cx semicolons are quite explicitly required, right?

Next, I’m working on a Mac, now. If you know me, you’ll know that this is, like, a huge deal for me. It’s just a work machine, AND it’s four years old, buuuuut it’s great for coding even if it’s comically bad at other things, i.e. file management (honestly does anybody EFFECTIVELY use Finder? my theory is that apple wanted to ensure that their file management system was different than windows’ [whose Explorer {directories, not internet} is superior to all others] and now they’re too bashful to back out???). The mouse pad, though, is a serious delight to use, the best touch pad I have ever operated on, and the keys are lovely to type on. It’s strange having no optical drive (it’s an Air) and the minimal number of USB ports can be frustrating, but of course, a $1300 machine is a $1300 machine, and a professional versus hobbyist (read: my perfectly delightful $600 2.5y/o windows/ubuntu machine) computer is going to be a vastly different user experience. I hate the fanboyism around macintoshes so, so much, though, that I probably will still never buy one on my own, but it seems you need to be comfortable with them to work in tech, at least in Portland. So here I am. A bit blech, a bit “oh this works really well.”

Lastly, I’m volunteering with a group called Chick Tech right now, which assigns mentors in industry to young women. It’s a very cool organization, and I can already see myself staying involved with them for a long time. I worry about this approach to solving one of tech’s many diversity problems, though – the problem, at this point, is not to interest young women in STEM, but to keep grown, adult women in tech once we are here. And here, we are, and I/we will demand equality. Jessica McKellar and Selena Deckelmann, a couple of fabulous tech luminaries whom I follow, both refer to the “leaky pipeline*,” – we can get them in, but we can’t keep them there. I think the following tweet from Jenny Thurman sums up the issue quite well.

So I will continue to think about this while I have a blast with my mentee, a motivated young lady whose trajectory I am excited to follow and encourage.

* the earliest reference I have found to this particular use of this term is from a paper from 1996, found here.