Top Tips for a Junior Developer

Hi! I’m back!

I took a 6 month hiatus from blogging, primarily because I originally viewed it as a tool to get a job…and then I got a job!  I received an offer 2 weeks after graduating bootcamp in December (merry Christmas to me!) and started as a junior developer in January.  6 months in and I’m LOVING it.  Since beginning, I’ve learned a ton, and I would like to document in some way.  So here I am!  While this blog was certainly effective for landing a job, I also think it’s a useful tool for me to articulate what I know about various pieces of technology, develop metaphors to help me understand them better, and fill in the gaps in my knowledge that are inevitably revealed in the writing process.

I wrote up a list of topics I plan on covering in future weeks (python magic methods, security vulnerabilities, jquery, selenium, git…) but for now my mind is on what advice I would give to Maddie-from-6-months-ago: fresh out of bootcamp, and starting at a new company as a junior developer for the first time.

Tip 1: Write down any unfamiliar words you hear, and research them later.

On my first day, I attended stand-up at 10am just like I have every workday since then.  Now, it’s a helpful way to get an idea of what everyone on the team is working on…but on the first day it genuinely sounded like everyone was speaking Italian (…and I don’t speak Italian.)  After that first standup, I made a list of all the words I hadn’t understood, and I kept adding to that list throughout the first few weeks.  Eventually, I would go through and search them in our team Confluence (note: Confluence was DEFINITELY one of my mystery words) and on Google.  I was just looking for the basics.  I learned that Confluence is a tool to “create, collaborate, and keep all your work in one place.” Great! Next! This made stand-up start to feel more like it was being spoken in French (…I dabble.)  Nowadays, I feel fluent.  I definitely can’t tell you everything about the Bugsnag API, for instance, but if someone mentions Bugsnag in passing I at least have a reference point.

Tip 2: Make yourself a git cheatsheet and tape it next to your monitor(s).

Git is an extremely common version control system (don’t know what that means? Add it to your list right now!)  It’s also a tangled web of commands that don’t always work how you intend them to…and there’s no ‘git undo’ command.  I am absolutely not a git expert, but one of the best things I did in my first few weeks of contributing is make myself a handy cheatsheet that makes me SEEM kinda like a git expert…or at least git competent.  The contents of this cheatsheet depend on your level of expertise.  I already had the basics memorized (git checkout, git pull, git add, git commit…)  My cheatsheet is more of an, “oh heck I have made a terrible mistake, please help me” kind of guide.  Here are the contents of my cheatsheet:

  • Discard all commits on branch: git reset –hard <last good sha>
  • Discard last x commits: git reset –hard HEAD~x
  • Add a change to commit without editing message: git commit –amend –no-edit
  • See files in a commit: git show –stat <sha>
  • Only merge one commit into a branch: git cherry-pick <sha>

I add to this list whenever I realize that I’ve googled the same thing more than a few times.  I just added git cherry-pick to my list this week.

Tip 3: Embrace the search-entire-codebase feature in your text editor.

I’d say that I search my entire repo about 1 jillion times per day.  Here’s my workflow for locating the code I need to edit for a ticket: find a key word in the ticket, and search the entire GIANT repo for it in my code editor (I use Sublime.)  It’s actually pretty fast.  Obviously, the quality of your key word is…key.  If you have to dig through every instance of a function that gets called 1000 times, pick something more unique to search.  One time I accidentally searched my entire codebase for the word ‘if’…and I crashed my editor.

I also use this method to find where functions I’m working with get called from.  It’s a very helpful way to trace backend code back to the frontend so I can test it.

Tip 4: Figure out a method to keep track of your tickets.

My company uses Jira for ticket creation, and there are built-in tools in place to manage tickets.  You can save customized searches to help you locate specific tickets, and create personal dashboards based on the searches you write.  Here’s a simple search to find tickets that are ready to be worked on or currently in progress, and assigned to me:

Screen Shot 2019-06-28 at 10.43.17 AM

While I definitely use my dashboard, I also found that a tracker in my notebook works best for me.  The current version has my tickets on the y-axis and the stages of development on the x-axis.  I like to check off the stages as my tickets moves closer to production so I can see at a glance where all my tickets are at any one time (even if they’re currently assigned to QA).  If you prefer digital tracking, that’s cool too – just get a system that works for you, because losing track of a ticket is no fun.

Tip 5: Write down notes and questions for each bug (especially on Fridays!)

58343045260__0E401E8F-615E-4314-8090-CBCF97A3190D
A portion of one page of my dev notebook.

I like to jot down notes for the larger tickets that I work on so I have somewhere to reference when I return to the ticket later on.  As you likely gathered from my ticket tracking system, I prefer pen-and-paper notes, but I can see this working equally well digitally.  A lot of times, my notes are just relevant files and what calls them.  Sometimes, I make a to-do list based on the ticket’s technical specs to make sure I don’t miss anything.  This is SUPER helpful on Monday mornings when I sit down to work on ABC-1234 and don’t have to re-find where the function I’m editing lives in my repo.  It also helps me articulate better questions for senior devs when I get stuck.

These 5 tips have helped me stay productive and organized in my first 6 months as a developer, and I know that I’m going to learn many more strategies over the next months (and years!) of my development career.  What tips have helped you most at work?

The Top 5 Most Forked Github Repos: 2018

It’s almost 2019, and what a year it’s been.  One year ago today, I was struggling to get through the final few days before winter break as a tenth grade math teacher, and struggling to convince my advisees to get their college apps in and their college visits completed.  Today, I’m sitting comfortably on the other side of Fullstack Academy’s software engineering immersive and spending my week interviewing and completing coding challenges….whew!

As a new software engineer with some time on my hands, I found myself wondering about the most popular Github repos OF ALL TIME.  I’ve certainly forked a fair few in my day, but what are the best ones?  The most popular ones?  Well, here you go.  In this post, I’ll list the repos, and then try to explain and/or uncover why they’re so popular.

Screen Shot 2018-12-19 at 7.15.20 PM
To find the top 5 most forked repos, you can search Github for ‘stars:>1’ and then sort by ‘Most forks’ on the righthand side of the page.
  1. datasharing by jtleek

Wouldn’t it be great to be able to list the most forked repo of all time on your resume?  This one is interesting, because it’s just a README!  Like, a really good one, but still.  As of this post, it has 191,505 forks and 4,580 stars.  Issue #217 on the repo asks why it’s the most forked of all time, and the top answer says that it’s a required fork of a Coursera course that focuses on Github.  I asked a world-renowned data scientist (my husband) about this repo, and here was his response:

Screen Shot 2018-12-19 at 7.28.57 PM
We were texting from 2 rooms away.

2. ProgrammingAssignment2 by rdpeng

This is an assignment for a Coursera course in R that asks students to cache some computations.  Is Coursera advertisting this stuff somewhere?  That the top 2 Github repos of all time are forked by their students?  As of this post, this repo has 114,434 forks and 567 stars.  Questions raised by this repo: Where is ProgrammingAssignment1?  Does it not require a fork?

3. Spoon-Knife by octocat

This repo is an example of how to fork a repo!  Makes sense that it’s been forked a fair few times.  Also…get the name?  GET IT?  As of this post, this repo has 101, 816 forks and 10,079 stars.

4. tensorflow by tensorflow

Now we’re getting to the good stuff!  From the README:

TensorFlow is an open source software library for numerical computation using data flow graphs. The graph nodes represent mathematical operations, while the graph edges represent the multidimensional data arrays (tensors) that flow between them. This flexible architecture enables you to deploy computation to one or more CPUs or GPUs in a desktop, server, or mobile device without rewriting code. TensorFlow also includes TensorBoard, a data visualization toolkit.

This repo was created by the Google Brain team, and is used and interacted with in Python, although it performs a lot of the work using C++.  TensorFlow essentially makes machine learning easier to work with by abstracting away a lot of the messy details.  It allows a developer to focus on what they want to happen and what the logic should look like, rather than fussing around with the specific inputs and outputs of various functions that you need to string together.  Instead of learning how to create my own deep neural network from scratch, I can use TensorFlow.  It was first released by Google as an open source project about 3 years ago (November 2015.)  It’s cool.  Five stars.  Here’s a video of a talk called Effective TensorFlow for Non-Experts, originally presented at Google I/0 2017, that does a good job of explaining its purpose and functionality.

As of this post, TensorFlow has 70,708 forks and 117,010 stars (and is the first repo on the list with more stars than forks – you go, Glen Coco!)

5. bootstrap by twbs

There’s something oddly pleasing to me that the #4 most forked repo was a deep, data-heavy, backend kinda tool whereas the #5 repo is a frontend framework.  It’s Bootstrap!  Bootstrap was initially created by Twitter developers and was initially released in 2011.  I’ve never actually used Bootstrap, being more of a Semantic UI kinda gal myself, but I remember hearing it thrown around all the time and eventually googling it to see what the deal was.  Essentially, Bootstrap has a ton of built-in CSS and JS that allows you to make your site look pretty without having to reinvent the wheel every time.  If you’ve used something like Semantic UI or Material UI, you’re probably familiar with the general concept of a frontend framework.

As of this post, Bootstrap has 63,605 forks and 129,469 stars (and one of the stars is from me!)

So there you go!  The top 5 most forked repos.  I think it’s fascinating to peek into what other developers are forking, and I’m already considering a future post to delve into the top 10 most forked repos (potentially ignoring any repos that are course-specific assignments…)

What’s the most useful repo you’ve forked?

Creating a Seed File with Neo4j

Neo4j is a graph database that differs from a more traditional relational database (like a SQL database, for example) in the way that it stores relationships between nodes.  While a relational database can hold foreign keys that reference other model instances, Neo4j has edges that connect nodes, and these edges are POWERFUL.  An edge isn’t just a blank connection, it can hold information about the connection and has a direction.  If I follow you on Twitter, there might be an edge connecting our nodes that says how long I’ve been following you (I have no idea how Twitter works, is that obvious?) The node would be unidirectional if I’m following you and you’re not following me, or it could be bi-directional if we’re mutually following one another.  Queries are also written differently, in a language called Cypher.

Just as thinking about database relationships in graph form involve a bit of a paradigm shift, thinking about seeding data involves similar flexibility.

A bare-bones PostgreSQL seed file may have a function like this:

Screen Shot 2018-11-16 at 10.10.30 AM

I’ve imported my database (db) where I defined all of my models, and I’m mapping over a campus array and a student array.  Both of these arrays contain instances that match up to the way I set up the models.

Neo4j seeding is a similar idea, but different in actual implementation.  The similarity is in what you’re feeding into your seed file.  It’s still expecting some data structure that contains a bunch of future-nodes – the things you’re putting in your database.  For this particular project, I was seeding my database with recipes and ingredients.

Here’s what one recipe looks like.  The recipes were generated as a result of scraping a website, so they were kind of wonky JSON objects:

Screen Shot 2018-11-16 at 10.15.02 AM

Okay, onto the actual seeding.  The function that is actually invoked within this seed file is called runSeed.  It’s essentially a helper function with some helpful console logs and 2 asynchronous functions, recipeSeeder and seed, nested inside of a try/catch.

Screen Shot 2018-11-16 at 10.17.16 AM

The seed function being invoked within runSeed is just like the PostgreSQL campus/student seed file discussed above.  For this project, we used the Neo4j database for everything, but we also had users stored in a relational database because our boilerplate code already included login/sign-up functionality that relied on it.  Why fix what ain’t broke?  We kept it.

The recipeSeeder function is what we wrote to create the rest.  It does 4 major tasks:

  1. It finds all nodes currently in the database, and deletes them.  This is the equivalent of running db.sync({force: true}).  We get a clean slate to start seeding.
  2. It makes assertions for the nodes we’re about to create.  We asserted that the recipe names were unique and that the ingredient names were unique.
  3. It maps over all the recipes in the database it receives as an argument and runs a Cypher query to create a new Recipe node if it doesn’t exist already.
  4. It maps over all the recipe’s ingredients and runs another query to create new Ingredient node if it doesn’t exist already.

Here’s the function as a whole:

Screen Shot 2018-11-16 at 10.36.11 AM

I thought about deleting the comments before adding this picture, but I added them to explain to my group members what was happening and I think that they’re helpful.  Same with my linter’s yellow squiggles – this is in-progress code here!

Lines 37 – 43 are doing the housekeeping: clean up all prior nodes, and make sure Neo4j knows we don’t want any duplicates.

Lines 46 – 57 are creating the Recipe nodes.  The Cypher query is in yellow.  MERGE finds an existing node or creates a new node with the parameters included in the braces, and it returns the node it finds or creates.  You could use template literals within the query to have the query interpret variables, but the structure used here is more secure and protects against injection.

Lines 58 – 78 are creating the Ingredient nodes.  We iterate through the ingredients on the recipe and run another MERGE query, then we build the relationships.  MATCH looks for a Recipe node and an Ingredient node, and the WHERE clause specifies what it should be looking for.  Here, we want the name of the Recipe to be our current recipe and the name of the Ingredient to be our current ingredient.  Then, we use MERGE again to check if there’s already a relationship.  If there’s not, MERGE builds it.  We decided to place 2 pieces of information on the edge/relationship created: quantity and type.  If my recipe calls for 2 tablespoons of honey, quantity would be 2 and type would be tablespoons.  This will allow us to implement sliders for increasing recipe quantities later on.

Lines 79 – 83 are more housekeeping: close the session, and close the driver.  Tie up everything with a nice, neat little bow.  Seeding is done!

Of course, errors are possible.  Before we used MERGE we were using CREATE (because that is a logical word to use when you’re trying to create nodes), but because of our unique constraints errors would be thrown if attempting to create a node that already existed.  MERGE solved that problem for us.  Another weird quirk about Neo4j is that you’ll get an error if you try to seed the database when your connection isn’t open – makes sense, but always takes me by surprise.  You need to go into the Neo4j browser and connect before running any queries.

So that’s it!  I’ve been using Neo4j for a grand total of 3.5 days at this point, so I’m sure I will look back on this article in a few weeks and groan, but I think it’s beneficial to chronicle my experiences with new technologies nonetheless.

 

The Mysterious Magic of Webpack

This week we finished up our e-commerce group projects on Wednesday and then started a short solo hackathon sprint.  I decided to explore a machine learning API called Clarifai to build an app that can recognize houses, faces, and houses that look like they have faces.  It’s not quite done yet, so more on that later.

I started this project using boilerplate code, and I realized that there was a lot of magic going on behind the scenes that I didn’t fully understand.  Generally, I knew what all of the different libraries were doing (Travis was doing something with testing before deploy, webpack was bundling code, etc.)   I’ve decided to investigate each of these libraries that I came across a bit more deeply, because I want to be able to provide more eloquent explanations of the tools I’m using to support my code.

First up: the mysterious Webpack.

After reading through the documentation, I’m using a metaphor of a vacation packing list to help me understand what webpack is doing with my JavaScript files.

  • Webpack is a static module bundler.  Modules are chunks of functionality.  Imagine that my packing list is on my computer and I’m using links to other, smaller packing lists that live elsewhere.  Let’s say that my Clothes packing list module includes a link to a Beachwear list, some items I’ve just typed in, and another link to a Hiking list.  The bundle created would include all of the other lists referenced, which are called dependencies.  Bundling allows the browser to load fewer chunks of information in order to display your app – instead of having to click through to see all of these packing lists, it just gets one master list to display.
  • The webpack entry point is like saying, ‘Hey application!  I’m gonna give you some bundled instructions, and to do them, you gotta start at the Clothes part of the list.”  Webpack defaults to using ./src/index.js as its entry point, just like I default to starting by packing clothes first.  Both of us are flexible if given other specific instructions.  Maybe you’d prefer to start packing your makeup first.
  • The webpack output is like saying, ‘Hey application!  I made you all these nice instructions on how to pack for your trip, and I’m putting them all together in a list named [something].bundle.js.  Webpack defaults to ./dist/main.js, but again, that can be changed in the config file.
  • Loaders allow webpack to interpret files it’s not typically familiar with.  Without loaders, webpack can handle JavaScript and JSON.  Loaders are like giving webpack the tools to read some of the packing list that’s in French without freaking out.  It can still include those files in its master packing list file.

There are other components of webpack that I haven’t touched on here, but going through the basics and comparing them to my imperfect-but-helpful packing example definitely makes me more clear about what webpack is doing with my application.  It’s essentially a streamlining tool that takes a whole mess of files that all reference each other and creates a simpler, fewer-layer to do list for the browser to implement.

 

Express 101

Express is a web framework that allows JavaScript programmers to write on the back-end in a language that was originally considered exclusively a front-end language.  Express is layer on top of Node.js that gives it functionality that a web app needs: Middleware!  Routes!  Static file serving!  You could do all of this stuff without Express, but you would have to write a ton more code.  Node.js with express vs. without is like the difference between buying puff pastry form a store vs. trying to make your own.  One is way harder and ends up tasting the same in the end.

Some great things that Express allows you to do:

  • Easily write request handlers!  Request handlers are instructions on what to do when an HTTP request comes in.  Here’s a simple example that says “when you hear a ‘GET’ request for the path ‘/’, send them all the categories.  Screen Shot 2018-11-03 at 9.52.26 PM
  • Export your own modules!  That’s the module.exports part of the code above.  Modules are just JavaScript files (or libraries) that you can import into other files.  Here, I’m exporting my router so that I can use it in other places in my code without having to rewrite everything.  On the other end, I would use the require syntax to import my router.
  • Incorporate middleware!  Middleware are various steps that serve all kinds of useful functions like handling any errors that occur, authenticating users, or logging requests to the console so you can see them as they occur.  Static() is a useful built-in middleware that serves up static files like HTML and CSS files so they’re sent along with any request.
  • Incorporate databases!  Express doesn’t care which database you like, it’ll make it work.  You can require your database and then perform any CRUD (create, read, update, delete) operation on your instances.

So that’s a brief overview of Express!  It’s non-judgmental about a lot of things, like how your organize your files, which modules you use or create, and which database mechanism you prefer.  It’s also bare-bones, meaning that a lot of its power comes from learning which libraries to use to complete certain tasks.  I’m definitely still figuring out my preferred setup, and I’ll let you know as I figure out more of my preferences.