Distance Running and Software Engineering

Have you ever found something you enjoy so much that you just want to continue doing it for as long as possible? Is it coding? Is it building things? Well, for me it is.

What about other things that you enjoy? Are they similar or different to what you enjoy the most? Are they completely different? It's fine either way. But does one complement the other in a way you really never thought it would until you really got into it?

Distance

Distance running is that other thing for me. I did not get into running until more recently in my life, but it has been one of the things in my current life that has helped me be a better engineer.

"What?" Yes, something non-technical has helped me be a better engineer. "How so?", you may be asking; well, let's go through some of the things that are in common and have helped me. On your mark, {airhorn}. (I promise, I'll try and keep the racing references to a minimal.)

In the Zone

The one thing I enjoy about coding is getting into the zone. That state of being where you are so focused at getting something done and everything and everyone around you are out of mind. The joy of being in a rhythm and a constant cadence of feeling productive; always working towards a goal whether it be something small or something large (maybe both).

Now, what if I told you that I feel the same way when running? The feel of being in the zone; that meditative state, clearing your thoughts and constant cadence. For the non-runners out there I can probably get a sense of skepticism coming, but this feeling is felt by other runners. If you don't run, think about something else you may do that is calming for you. I've heard that knitting, baking, or gardening are also quite calming.

Finding that passion outside of work has been such a pleasant surprise. It's a wonderful day if I am able to get into the zone and clear my mind whether it be with running or programming or even both.

Team Work

As a software engineer, I have a team that comprises of other engineers, a tech lead, a product manager (PM), an engineering manager, a designer, and a Product Marketing Manager (PMM). What is my role within the team? If you said, "code", yes, you are absolutely correct. But that is only part of the answer, because afterall, software engineering is not all about code. (Something I had only come to embrace later in my career.)

Let's think back to running again. So as a person who likes to keep on track with goals, my natural progression in running drove me towards racing. Let's think about that word rigth there first, "racing". You typically think of racing as a competition where you would be running to get to the finish in the fastest time posssible. While this is mostly true, for most folks it's really just a competition with yourself; a competition to compete with your former self and get to that finish line faster than you had done before. You can think of the elite runners and of course they're competing to finish first. But for most of us, we're simply competing to get that personal best.

I've learned to think of pace as a team effort. When running with others, I'll sometimes make that concious decision to pace slower to pull other runners along with me and have us draft together; working together. But thinking this way has also been good for me as an engineer. While I may be a fast programmer (sometimes), if I am the only engineer that is fast does not necessarily mean the project I am working on will be finished earlier. What happens then, if as a team we work together, whether that means me taking some time out of my day to show other folks how to do something or perhaps as a team we stop to talk about a solution? Maybe then we won't waste too much time duplicating efforts or missing learning opportunities.

I fear that it is often that we, as engineers, forget that we are working as part of a bigger system. While our day to day tasks may be engineering the bigger picture involves quite a bit of peopleware. Pace is relative, work together with your teammates, and you are collectively fast.

Data

Let's talk about data. Data is obviously important for a lot of decision making. I mean this in the aspect of both running and software engineering. This one bit is actually one of the aspects of software engineering that has actually made me a better runner, but also still a better engineer.

Quick story time; flashback to my first ever half marathon. It was the Staten Island Half Marathon. I had trained for it, but I had convinced myself that I could run a qualifying time for the NYC Marathon.

Spoiler alert: I didn't make that goal. But if I looked back on my data for my training that led up to this race, I would've already known that my goal wasn't realistic. I did not come close to the right pace I needed to be at in any of my training runs and I should have acknowledged that before committing to attempting that pace during a race.

So how did that race go? Well, I went out hard at the pace I needed to be and well, I didn't make it all the way pacing that fast. I will just say that I finished a good ~17 minutes slower than where I wanted to be.

So what did I learn from all of this? Know your data and know it well. For most of my important training runs, I take a look at the data (Strava) and get a good gauge on how my training is going. I'll constantly make adjustments to make sure I'm headed in the right direction.

Feedback is data; remember that. Think about software projects; are you constantly learning about your progress? I can tell you that, it's a lot easier to pivot earlier on than when you have already built something and invested a lot of engineering time and effort. If you are practicing agile methodologies and have done waterfall in the past, you can probably relate! Ask for some feedback from your stakeholders, whomever they may be (your manager, your tech lead, designer, PM, et cetera). Those fine tuning knobs are there for you to adjust and make everyone more efficient.

Long Term Goals

It's not a sprint, it's a marathon. Yes, let's just get that saying out of the way now; it is a very valid statement though. At the time of this writing, I am happy to say that I have successfully completed five marathons. But getting to this level, did not happen overnight. I recall when I first started out running, the amount of soreness I had from just a 5k (~3Mi) jog. It was prety painful and awfully tough. But after a while, my body adjusted and I had become accustomed to what works and what doesn't for my running.

Do you know what that sounds like though? That sounds exactly like my engineering career. When I first started I was scared, anxious, insecure, but also just willing to put in the effort to make those feelings less amplified. Note that I say less amplified because I will be honest, that there are some times to this day, that I will still have those feelings.

Consider a a new big project that you promise to deliver; the project as a whole may seem quite large and overwhelming, but if you break things down and focus on pieces of the whole little by little, it's just so much easier to absorb. So, whatever you may be working on, whether it may be training for a race of any distance or building out an application of any size, remember that there is always a finish line and you can get there little by little.

By Adrian Cruz | Published March 30, 2019, 9:55 p.m. | Permalink | tags: engineering, running, software engineering

Three Years of Searching

So, many folks have asked me how I’m feeling after my work anniversary of three years has passed. Honestly, my initial reaction is, “well, it’s only three years!”. But it has come to my attention that for a lot of folks nowadays, three years is probably the longest they have been at a company.

What I Learned

A lot. That is a good thing; technology is an ever-changing field and if you want to stay relevant, you want to be consistently learning.

Information Retrieval

I was new to the information retrieval space, so learning about indexing and search ranking was such a joy. This may probably warrant its own section, but A/B testing is something I learned quite a bit about since my team tests just about everything.

Programming

I learned Elixir, which was my first functional language. I learned quite a bit about frontend technologies like React and NodeJS. I learned to be okay with pairing; I can’t say that I love it, but I don’t hate it.

Infrastructure as Code

Chef, Kubernetes, Docker were all new to me. Maybe these are a bit rudimentary for some folks, especially if you do not work on infrastructure and only do product work. But, if you like autonomy and work on just about anything, understanding the infrastructure that your code runs on is key for optimizing things.

Peopleware

This sounds cliche, but it’s true so I’m going to say it anyway; the people here are what makes it awesome. When you work at larger organizations, it’s easier to fade into the background. But in a smaller sized company, you’ll be able to find yourself making connections with everyone and knowing what they like, what they dislike, when they’re having a rough day, when they’re thriving and excited to push out new features.

Looking Further Back

The landscape has changed quite a bit. Well actually, a whole lot; we moved offices! I’ve honestly lost count on how many seats I’ve had along the years. But looking at our tech stack and our processes, it’s an entirely different place. I like to bring up the old ways of “deploy days” when someone new complains about our current deploy process pains. Yes, I said, “deploy days”; we didn’t do continuous deployment, we deployed code once a week with an assigned engineer to do the deployment. Things are nicer now, we have pretty decent processes in place and are constantly sending out surveys to find any pain points.

Onward

I think I’ve mentioned that three years is a pretty short time for me. But since folks asked if I was going to write up something, I could not disappoint. I have goals to give more talks and contribute more to the open source community. I also have a goal to write more often and not just focus on code. Crazy right? We’ll see if I can hold myself to that. Onward, cheers!

By Adrian Cruz | Published Aug. 4, 2018, 8:30 p.m. | Permalink | tags: retrospective, software engineering

What Does Fibonacci Look Like in Elixir?

I recently had a conversation about Elixir since I have been using it more and it was not a language this person was familiar with. As curious engineers, one basic question that arose was, "what does Fibonacci look like?". I was happy to comply and provide some code.

As a quick refresher, we want to write a function that takes in an integer that represents the nth number in the Fibonacci sequence. For this implementation, we're assuming that the input is a non-negative integer. Okay, let's go!

Recursive

So the typical recursive solution has a function fib(n) and we return an integer of 1 if n is equal to 0 or 1 and otherwise, we want to recursively call fib with the last two previous indexes.

def fib(0), do: 1
def fib(1), do: 1
def fib(n), do: fib(n-1) + fib(n-2)

Happy days! We just need three lines to implement this! Now, if you recall my previous post on Elixir function conditionals, that is the same thing we're doing here. We're returning 1 if we pass in a 0 or 1 index, otherwise we'll just do the recursive logic that we want. That's it!

Iterative

"So what about an iterative solution?" you ask? Yes, that's actually what was discussed next anyhow. So, the typical solution for an iterative solution is to have a loop and have two variables track the previous and current values. So, that's fine, but something just felt wrong with that not being quite Elixir-y. So, I thought about it for a bit and came up with the following solution.

  def iter_fib(0), do: 1
  def iter_fib(1), do: 1
  def iter_fib(index) do
    Enum.reduce(2..index, [1, 1], fn(_i, acc) ->
      # Calculate the Fibonacci value
      fib_val =
        # Take the accumulator
        acc
        # Flatten the list since we're appending fib_val by a new list
        |> List.flatten()
        # Sum those values
        |> Enum.sum()
      [Enum.take(acc, -1), fib_val]
    end)
    # This is now the Fibonacci value for the index and its previous value, so just take the last value
    |> List.last()
  end
So, what I've done here is create a list that represents the Fibonacci sequence. We have the same overloaded function signatures for index values of 0 and 1, and otherwise, the bulk of our code goes into our Enum.reduce/3. What we are doing is constantly keeping the list length at 2 so we can easily just sum the values and compute the next Fibonacci value. My first implementation actually was a bit memory hungry because I was just appending my list continuously and then taking a sum of the last two values. Why keep the list long if you only want to compute that last value right?

And Bob's Your Uncle

That's it! Plain. Simple. Memory smart. Anyhow, you can checkout the full source here in this gist. Cheers!

By Adrian Cruz | Published Aug. 19, 2017, 10:08 p.m. | Permalink | tags: elixir

Read older entries