The Reality of “Code Challenge” Culture Outcomes Among Large & Small Organizations

Key definitions for this article:

“Code Challenge” Culture: This culture is more of a “do as we say, we’ll grow you as we see fit, and you may then continue with us if you perform accordingly” type of environment. It starts with a more defined, strict adherence to an academic achievement type environment that enforces one do things a certain way and follow a certain path, and to ensure you too will do those things a code challenge is used to gate keep a particular job role. There are obviously good and bad results to this culture, and this article is going to get deep into those cultures.

Wholistic Culture: This culture is more open to getting a larger picture idea of a candidate in the interview pipeline. With more of an intent around having the individual develop the organization and for the individual to learn. The possibility of bringing knowledge that can help one improve the organization is readily accepted as is an individual that might not pass a rigorous academic code challenge to shift arrays, or move bits, or trickle values around a binary tree! There are however, good and bad outcomes to this type of culture.

Caveats: In both cultures there are numerous additional criteria that changes them. In this article I’ll write about them in a general sense, and then when detailing something specific, I’ll state that caveat with a call out.

The Big Organizations & Smaller Niche Organizations

I’m going to use three big companies and three small companies here that have varying degrees of “Code Challenge” Culture. In that, I’ll dive deeper into the problems that arise from a strict “Code Challenge” Culture vs. a Wholistic Culture.

Continue reading “The Reality of “Code Challenge” Culture Outcomes Among Large & Small Organizations”

A Guide Path for Strategic Growth and Leadership in Software Development

Growing a development team is somewhat parallel to building a skyscraper. You start with a solid foundation – you’d at least hope – add floors with meticulous planning, and eventually, you reach the pinnacle with strong leadership guiding the entire structure. In software development, this process involves strategic hiring decisions at various stages. Let’s delve into why focusing on Senior and Mid-Level developers initially is crucial, the role of Junior developers in the maturation phase, and the point at which hiring Principal developers becomes essential.

Continue reading “A Guide Path for Strategic Growth and Leadership in Software Development”

An Engineering Manager Challenge

This post came to mind while reading this post on LinkedIn, which is a share of this post by Kelvin Mai, and the follow up post Ted Neward made here. Read up on those for more insights into this topic.

Before diving into the details, it’s important to note that the criteria outlined here leave several questions unanswered, which could significantly impact the final decision. Factors like the specific nature of the projects, team dynamics, and long-term strategic goals are crucial and could sway the decision in different directions. That said, let’s break down the options.

Bringing on Two Junior Developers

Pros:

  1. Boosted Bandwidth: Two fresh faces mean more hands on deck to share the workload, increasing overall throughput.
  2. New Blood, New Ideas: Junior hires come with fresh perspectives and a ton of enthusiasm that can rejuvenate the team.
  3. Long-term Investment: Junior devs are like seedlings; with the right nurturing, they grow into valuable assets, contributing more as they develop.
  4. Flexibility: Juniors can be shaped to fit the team’s needs and culture, making them adaptable assets.

Cons:

  1. Boosted Bandwidth: Emphasis here though is on “throughput” above in the pros and not on committable, usable, and well written code you want and can use in the project. Increased throughput can be a negative, and IYKYK and can think of this as “induced demand” but for code.
  2. Training Time Sink: Juniors need a lot of guidance, which can be a major time drain for the senior members.
  3. Ramp-up Period: They won’t hit the ground running. Expect a learning curve before they start delivering at full capacity.
  4. Management Load: More people means more management. Even if they’re juniors, it adds to the admin overhead.

Hiring One Senior Developer

Pros:

  1. Expertise on Tap: A senior dev brings a treasure trove of knowledge and experience, perfect for tackling complex challenges and making strategic moves.
  2. Mentorship: They can mentor junior team members, leveling up the entire team’s skill set.
  3. Quick Impact: Seniors can dive in and start contributing much faster than juniors, thanks to their experience.

Cons:

  1. Higher Price Tag: Senior talent doesn’t come cheap. They’ll command a higher salary, impacting the budget more significantly.
  2. Cultural Fit Risks: There’s always the gamble that a senior hire might not mesh well with the existing team dynamics.
  3. Single Point of Failure: Relying on one senior dev for critical tasks can create dependencies, potentially leading to bottlenecks.

The “Do Nothing” Route

Pros:

  1. Save the Budget: Not hiring anyone saves money, which could be redirected elsewhere.
  2. Focus on Current Team: No new hires mean you can double down on developing and optimizing the current team.

Cons:

  1. Opportunity Cost: Leaving budget on the table means missing out on potential gains in capacity and productivity.
  2. Burnout Risk: Your current team might end up overworked, risking burnout and decreased morale.
  3. Stagnation: Without fresh talent, innovation can stagnate, and the team might struggle to keep up with growing demands.

The Decision

Let’s get real: not hiring anyone is likely the worst choice here. I know some would disagree in some situations, but if you’ve got budget allocated for new talent, use it! Even if the ROI isn’t immediate, it’s about positioning the team for long-term success. Hiring is an investment in the future—whether it’s two eager juniors ready to grow or a seasoned senior ready to lead and mentor. In this scenario, hiring one senior developer is the strategic move. You’ll get immediate expertise, mentorship for the juniors, and a stronger foundation for future growth. Let’s make that budget work for us and set the team up for success!

Addendum

This post attributed to leading me down the path to elaborate on staff and hiring details, including The Toxic Truth About Coding Challenges in Technical Interviews and then the elaboration on that post with The Reality of “Code Challenge” Culture Outcomes Among Large & Small Organizations.

Top 3 Refactors for My Hasura GraphQL API Terraform Deploy on Azure

I posted on the 9th of September, the “Setup Postgres, and GraphQL API with Hasura on Azure”. In that post I had a few refactorings that I wanted to make. The following are the top 3 refactorings that make the project in that repo easier to use!

1 Changed the Port Used to a Variable

In the docker-compose and the Terraform automation the port used was using the default for the particular types of deployments. This led to a production and a developer port that is different. It’s much easier, and more logical for the port to be the same on both dev and production, for at least while we have the console available on the production server (i.e. it should be disabled, more on that in a subsequent post). Here are the details of that change.

In the docker-compose file under the graphql-engine the ports, I insured were set to the specific port mapping I’d want. For this, the local dev version, I wanted to stick to port 8080. I thus, left this as 8080:8080.

version: '3.6'
services:
postgres:
image: library/postgres:12
restart: always
environment:
POSTGRES_PASSWORD: ${PPASSWORD}
ports:
- 5432:5432
graphql-engine:
image: hasura/graphql-engine:v1.3.3
ports:
- "8080:8080"
depends_on:
- "postgres"
restart: always
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${PPASSWORD}@postgres:5432/logistics
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
volumes:
db_data:

The production version, or whichever version this may be in your build, I added a Terraform variable called apiport. This variable I set to be passed in via the script files I use to execute the Terraform.

The script file change looks like this now for launching the environment.

cd terraform
terraform apply -auto-approve \
-var 'server=logisticscoresystemsdb' \
-var 'username='$PUSERNAME'' \
-var 'password='$PPASSWORD'' \
-var 'database=logistics' \
-var 'apiport=8080'

The destroy script now looks like this.

cd terraform
terraform destroy \
-var 'server="logisticscoresystemsdb"' \
-var 'username='$PUSERNAME'' \
-var 'password='$PPASSWORD'' \
-var 'database="logistics"' \
-var 'apiport=8080'

There are then three additional sections in the Terraform file, the first is here, the next I’ll talk about in refactor 2 below. The changes in the resource as shown below, in the container ports section and the environment_variables section, simply as var.apiport.

resource "azurerm_container_group" "adronshasure" {
name = "adrons-hasura-logistics-data-layer"
location = azurerm_resource_group.adronsrg.location
resource_group_name = azurerm_resource_group.adronsrg.name
ip_address_type = "public"
dns_name_label = "logisticsdatalayer"
os_type = "Linux"
  container {
name = "hasura-data-layer"
image = "hasura/graphql-engine:v1.3.2"
cpu = "0.5"
memory = "1.5"
    ports {
port = var.apiport
protocol = "TCP"
}
    environment_variables = {
HASURA_GRAPHQL_SERVER_PORT = var.apiport
HASURA_GRAPHQL_ENABLE_CONSOLE = true
}
secure_environment_variables = {
HASURA_GRAPHQL_DATABASE_URL = "postgres://${var.username}%40${azurerm_postgresql_server.logisticsserver.name}:${var.password}@${azurerm_postgresql_server.logisticsserver.fqdn}:5432/${var.database}"
}
}
  tags = {
environment = "datalayer"
}
}

With that I now have the port standardized across dev and prod to be 8080. Of course, it could be another port, that’s just the one I decided to go with.

2 Get the Fully Qualified Domain Name (FQDN) via a Terraform Output Variable

One thing I kept needing to do after Terraform got production up and going everytime is navigating over to Azure and finding the FQDN to open the console up at (or API calls, etc). To make this easier, since I’m obviously running the script, I added an output variable that concatenates the interpolated FQDN from the results of execution. The output variable looks like this.

output "hasura_uri_path" {
value = "${azurerm_container_group.adronshasure.fqdn}:${var.apiport}"
}

Again, you’ll notice I have the var.apiport concatenated there at the end of the value. With that, it returns at the end of execution the exact FQDN that I need to navigate to for the Hasura Console!

3 Have Terraform Create the Local “Dev” Database on the Postgres Server

I started working with what I had from the previous post “Setup Postgres, and GraphQL API with Hasura on Azure”, and realized I had made a mistake. I wasn’t using a database on the database server that actually had the same name. Dev was using the default database and prod was using a newly created named database! Egads, this could cause problems down the road, so I added some Terraform just for creating a new Postgres database for the local deployment. Everything basically stays the same, just a new part to the local script was added to execute this Terraform along with the docker-compose command.

First, the Terraform for creating a default logistics database.

terraform {
required_providers {
postgresql = {
source = "cyrilgdn/postgresql"
}
}
required_version = ">= 0.13"
}
provider "postgresql" {
host = "localhost"
port = 5432
username = var.username
password = var.password
sslmode = "disable"
connect_timeout = 15
}
resource "postgresql_database" "db" {
name = var.database
owner = "postgres"
lc_collate = "C"
connection_limit = -1
allow_connections = true
}
variable "database" {
type = string
}
variable "server" {
type = string
}
variable "username" {
type = string
}
variable "password" {
type = string
}

Now the script as I setup to call it.

docker-compose up -d
terraform init
sleep 1
terraform apply -auto-approve \
-var 'server=logisticscoresystemsdb' \
-var 'username='$PUSERNAME'' \
-var 'password='$PPASSWORD'' \
-var 'database=logistics'

There are more refactoring that I made, but these were the top 3 I did right away! Now my infrastructure as code is easier to use, the scripts are a little bit more seamless, and everything is wrapping into a good development workflow a bit better.

For JavaScript, Go, Python, Terraform, and more infrastructure, web dev, and coding in general I stream regularly on Twitch at https://twitch.tv/thrashingcode, post the VOD’s to YouTube along with entirely new tech and metal content at https://youtube.com/ThrashingCode.

Name Casing Conventions, The Quick Comparison

There are a number of name casing practices, which I’ll cover in quick fashion here, for variables and other objects when programming.

The Quickie Synopsis

  • camelCaseLikeThis
  • PascalCaseLikeThis
  • snake_case_like_this
  • kebab-case-like-this
  • MixAnd-match_like-this

Camel Case

With Camel Case the first letter of the first word is lower case, then every subsequent first letter of each word is upper cased. For example, thisIsCamelCasedsomething if a singular word, or somethingElse.

My 2 ¢ – I’m a big fan of this case when I’m name private variables or related objects. I’m also a fan of using Camel Casing for certain types of functions, especially in JavaScript such as this.doesStuff() or somethingAnother.doesOtherStuff().

Pascal Case

In usage of Pascal Case, the first letter of each word within the name is upper cased. Examples include ThisOjectThatThing, or WhateverElse().

My 2 ¢ – This is something I like to use for class declaracters (i.e. public class ThisClassThing) and then for functions or methods on that class, or respectively similarly for functions on functions in JavaScript, or the like. Basically, anything that will be used similar to MyThing.DoesThisThing().

Snake Case

Using Snake Case has the empty spaces replaced with underscores. So a file name like this is my filename.md would become this_is_my_filename.md.

My 2 ¢ – Snake case is great when I need to have variables that would otherwise have spaces, but also wouldn’t be displayed regularly with anything that might obfuscate the underscore, such as an HTML.

Kebab Case

Kebabs are tasty, the case however is similar to Snake Case, except instead of underscores dashes are used. Each space in the name is replaced with a - character. Such as my-table-name-is-this or this-is-a-variable.

My 2 ¢ – Kebab case is excellent for filenames, URIs, or something of that sort where spacing between the words of a file or path are important to read, but an underscore would be obfuscated by the font rendering such as with a URI.