FDE PulseFDE jobs open 434New in the last 7 days 27
VI

The newspaper of the Forward Deployed Engineer

Guides

Reading a customer's Java, Go or Node.js codebase when you only know Python

You don't need to learn a new language before the integration review. You need to know which three files to open first, then trace one request all the way to the database.

Kỹ sư ngồi trước laptop đang đọc mã nguồn trên màn hình, trong văn phòng hiện đại.
Photo: Christina Morillo / CC0

In brief

  • Every backend, whatever the language, follows the same flow: receive a request, process it, call a database or external service, return a response. Read along that flow, not by syntax.
  • Reading order: the manifest (go.mod, package.json, pom.xml), then the entry point, then the API routes or handlers.
  • The most common trap is carrying Python habits across: in Go a whole directory is a package, and in Node the "type" and "exports" fields decide how files are interpreted and imported.
ShareLinkedInFacebookX

It is your second day on site, and you have just been given access to the repos. Your team works in Python, but the order service your agent has to call is written in Go. The payment gateway runs on Java, and the API layer for the mobile app is Node.js. The integration review is this afternoon.

For an FDE, this is normal. The customer is not going to rewrite their systems to suit you.

The good news is that you don’t need to master any syntax before the afternoon. What you need is a map: which files to open first, what to skip, and how to answer the one question the customer cares about, which is where their data goes.

Every backend follows the same flow, whatever the language

In every backend, the server receives a request, processes it, sometimes queries a database or calls a third-party service, and returns a response. The API is the bridge between frontend and backend. So when you face an unfamiliar codebase, the API routes or handlers are the best place to start.

The syntax varies, but the flow is the same everywhere. So read with three questions, one at a time. What does the project depend on? That is the manifest’s job. Where does the program start running? That is the entry point. Which places does a specific request pass through? That is the handler, then the database or external service.

Newcomers often make one mistake: they open the directory and start reading from the first file in alphabetical order. Do that and you will drown in utility code before you know what the system does.

Three languages keep those things in three different places

The table below sets each language beside the equivalent you already know from Python:

Question Python Go Node.js Java (Maven)
What does it depend on? requirements.txt, pyproject.toml go.mod package.json pom.xml in the root directory
Where is the entry point? the main script the main function in package main the “main” field, or “exports” if present look for the main method under src/main/java
Where do main code and tests live? depends on the project in the package directories depends on the project src/main/java and src/test/java
What is a package? a .py file is a module an entire directory a directory with a package.json a branch in the package tree

Node has one more wrinkle the table can’t hold: whether a .js file is treated as CommonJS or an ES module depends on the “type” field in the nearest package.json. The last row of the table and this detail are where Python reflexes lead you astray most often.

Example: tracing an order through a Go service

Picture the customer’s order-service repo. The first step is to open go.mod. According to the Go documentation, this file defines the module and tracks the modules that provide the packages the code uses. From the dependency list alone, you can guess which libraries they use for HTTP and for the database.

The second step is to find where the program starts. In Go, the main function runs when you run package main, so you only need to find those two things:

cat go.mod
grep -rln "package main" --include=*.go .
grep -rn "func main()" --include=*.go .

From main, you will see where the server is set up and where the routes are registered. Suppose you find POST /orders pointing to a CreateOrder function in the api directory. Open that function and you come across a call to store.SaveOrder(...).

At this point your Python reflex tells you to look for a file called store.go. Don’t. A Go package consists of all the files in the same directory, so SaveOrder could be in any file in the store directory. Grep for func SaveOrder in that directory instead of guessing the file name.

The morning’s output should be a five-line trace. POST /orders goes into CreateOrder (api directory), then to SaveOrder (store directory), writes to the orders table, then calls the payment service. Bring that to the review and you can already ask specific questions: does the payment call retry, and which layer should the agent call into?

In Node, the first import error usually lives in package.json

Now for the mobile API layer; picture a repo called mobile-gateway. You write a small script to test the token-checking function, importing the package’s src/auth/token.js file directly. The script throws an error, and your first instinct is that the customer’s code is broken.

Open package.json first. Suppose it has an “exports” field that declares only the root path, pointing to ./src/index.js. According to the Node.js documentation, when “exports” is present it takes precedence over “main”, and any subpath not declared is hidden, so src/auth/token.js cannot be imported from outside.

The code isn’t broken; you are knocking on a door the customer has locked.

Suppose the same package.json also contains "type": "module". If the nearest package.json lacks this field or says “commonjs”, every .js file is treated as CommonJS. Here it is the opposite, so the files use import rather than require, and your test script has to be written the same way.

From src/index.js, you trace the route GET /orders/:id, whose handler calls the order-service you read that morning. The trace reads: “exports” exposes only src/index.js, route GET /orders/:id goes into the handler, the handler calls order-service. Three lines, and now you know the agent should call through the public API rather than poke at internal files.

In Java, let the tests guide you through the payment gateway

The Java payment gateway is easier to find your way around, thanks to Maven’s conventions. In the root directory there is a pom.xml, and only two main subdirectories: src and target. Application code lives in src/main/java, tests in src/test/java, and beneath each sits the package tree.

With a large Java system, read the tests first. Imagine you find a test class for the payment service in src/test/java, with one case checking an order with a negative amount and another checking a failed call to the bank gateway.

Those two test cases alone tell you how the system is expected to handle bad input and external failures.

Next, follow the same package branch over to src/main/java to open the class under test, then work back up to the controller that receives requests from order-service. The trace reads: the controller receives the payment request, passes it to the payment service, the service calls the bank gateway, and failures are handled exactly as in that test case.

This is usually faster than combing through every class layer from the top down.

The mistakes that turn a morning into three days

The most common mistake is believing you must finish learning the language before you are allowed to read it. You only need to read well enough to trace one request. Writing fluent Go or Java is next week’s problem, if the project really needs it.

The second mistake is carrying Python’s unit of module everywhere. You will look for a file in Go when you should be looking at a whole directory. You will ignore Node’s “type” and “exports”, then conclude that the customer’s code is broken.

The third mistake is reading without writing anything down. Without a trace, you have to start over the next day. And the customer’s people have nothing to confirm or correct for you.

Turn this skill into evidence when job hunting

If you are a Python developer hoping to move into FDE work, look for phrases in job descriptions such as “integration with the customer’s existing systems”. That phrase means you will be reading code you didn’t write, in languages you didn’t choose.

On your CV, don’t write “knows Go, Java, Node.js”. Describe a time you read a service in an unfamiliar language, traced its data flow and integrated with it successfully. A five-line trace is exactly the kind of thing worth bringing to an interview.

Customers won’t judge you on whether your Go is idiomatic. They will judge you on whether, by the first afternoon, you could show them where their data goes.

4 sources
Read next on the roadmap · Stage 2: Broad engineeringWhat FDE recruiters look for: code gets you in, customer communication sets the rankingYou cannot work as an FDE without coding. Once candidates have shown they can code, what decides who gets hired is how well they communicate with customers and win them over.