cswork / libraryOpen practice workspace

Interview guides · Datanational

Datanational Software Engineer Interview Guide

Datanational Software Engineer interview guide: RPG on IBM i, DB2, debugging, modernization and behavioral questions, plus a 7-day plan.

The 60-second brief

Candidates describe the Datanational Software Engineer role as RPG development on IBM i (AS/400) systems. The work is keeping existing business applications running, extending them and modernizing them. The workflows named are supply chain, manufacturing and distribution, and the role includes advising clients on how to get more from their systems. DB2 on IBM i is the database named for the role, and candidates also describe integrating RPG programs with web services and APIs.

This guide is for candidates applying for the Software Engineer position described as RPG development on IBM i. It covers the two reported rounds, the questions candidates report on RPG, DB2, debugging, modernization, testing, documentation and working with stakeholders, and a plan that turns those questions into spoken practice. It does not cover other Datanational roles.

Candidates report two rounds over roughly 2-4 weeks: a Screening Phase on your RPG and IBM i background, then Technical Discussions with senior engineering staff.

Focus areas

  • RPG Development (IBM i / RPG)
  • Software Engineering (General)
  • Code Quality & Maintainability

Overview

The reported questions read like a conversation about maintaining production RPG: which RPG versions you have worked in, how you handle file I/O on IBM i, how you debug logic errors in an old codebase, how you connect RPG to web services, how you change a DB2 schema, and how you test where a failure is costly. Preparation here means having concrete, rehearsed answers from your own projects rather than reciting syntax.

Two example scenarios candidates describe show the style: refactoring a monolithic program into smaller sub-procedures, and keeping data intact while moving between file formats. For both, practise a step-by-step answer: what you read first, what you changed, how you proved behaviour was unchanged, and how you would roll back. Pick one real program from your history for each and know it well enough to sketch on request.

Candidates also report that the role involves code reviews, working with project managers and advising clients, which is why the reported question list includes tight deadlines, explaining a technical constraint to a non-technical stakeholder, and documentation. Prepare at least one story for each, with a specific outcome you can state.

Candidates report that the screening stage asks about specific IBM i utilities and tools. Before the first round, write down the commands, debuggers and utilities you actually use day to day, so you can name them and say what each one told you on a real problem.

The Datanational interview process

Candidates describe two stages, the Screening Phase and Technical Discussions. The reported questions are grouped by topic, not by round, so prepare all of them for both stages.

Screening Phase

Candidates describe the Screening Phase as a check that your background in RPG and IBM i matches the role, and report that questions about specific IBM i utilities and tools come up at this stage. Treat it as a short, factual walk through your history: versions of RPG used, the kinds of programs you maintained, how you work with files and DB2, and the tools you reach for. Have two or three projects ready to summarise in a few sentences each, with your own contribution stated plainly.

What to demonstrate

  • Whether your RPG and IBM i background fits the role as described
  • Familiarity with IBM i utilities and tools you can name and explain
  • How clearly you describe your own contribution to past programs

How to prepare

  • Write a one-paragraph answer to the question about your experience with different RPG versions, covering RPG IV and free-form RPG, with one real conversion or maintenance example.
  • Make a list of the IBM i utilities and debugging tools you use, with one sentence each on a problem each one helped you solve.
  • Rehearse the file I/O question aloud, covering native record-level access and embedded SQL, and when you pick each.

Technical Discussions

Candidates describe Technical Discussions as a dialogue with senior engineering staff rather than a quiz. Reported scenarios include breaking a monolithic program into sub-procedures and protecting data integrity when moving between file formats. Expect to talk through debugging, modernization, DB2 schema changes, API integration, testing and documentation. Answer by narrating your method on a real case: what you checked first, what you changed, how you verified it and what the rollback was.

What to demonstrate

  • Technical depth in RPG IV, free-form RPG and DB2 on IBM i
  • Method for finding the root cause of logic errors in legacy code
  • Judgement about change risk in a production environment
  • Ability to explain trade-offs clearly

How to prepare

  • Practise the debugging answer as an ordered sequence: reproduce, narrow, inspect data and the call path, fix, regression-check.
  • Sketch how you would split a monolithic program into sub-procedures in a service program, including how you would confirm the output is unchanged.
  • Prepare a migration answer covering field mapping, packed and zoned decimals, dates, reconciliation counts and totals, and a rollback.
  • Outline an RPG-to-web-service integration end to end: who calls whom, data format, error handling and retry safety.

Where candidates lose points

Answering the RPG versions question with a list of release names and years

Anchor it to one conversion or maintenance task you did, such as free-form calculations replacing fixed format or a subroutine becoming a procedure in a service program, and say how you proved behaviour was unchanged.

Describing file I/O in generalities without saying when you use native record-level access versus embedded SQL

Prepare a short comparison: CHAIN and READE for keyed access, SQL for set-based updates, then locking and commitment control. Give one example of each from your own work.

Treating modernization as a rewrite, with no plan for keeping current business operations running

Describe an incremental path: wrap or extract logic into sub-procedures, expose it through a web service layer, run old and new output side by side, then cut over with a rollback.

Telling a batch optimization story with no baseline, no bottleneck and no check that the output stayed identical

State the before and after runtimes, the step you found dominant and how you found it, the change you made, and the control totals or record counts that matched.

Using stack jargon with a non-technical stakeholder, or claiming you document well without showing how

Practise a constraint explanation that opens with date, cost and risk. For documentation, name specifics: header comments on the purpose and change history, procedure interfaces, and notes on why a decision was made.

Questions & practice

Track a rolling failure rate per destination for circuit decisions

Easy · sliding window · ring buffer · circuit breaker

The egress service delivers about 1,500 webhooks per second across roughly 40,000 destinations, each call bounded by a 10 second timeout. Maintain, per destination, the failure rate over the trailing 60 seconds so a caller can ask before dispatch whether the circuit should open. Attempts arrive as (destination_id, finished_at_ms, outcome). Requirement: amortised O(1) per attempt, with total memory bounded by the destination count rather than by traffic. Give the structure, its exact memory, and the rule that stops a destination with three attempts from opening a circuit.

Approach

  1. Name the exact-deque version and then reject it as the default. Holding timestamps and advancing a tail pointer past anything older than now minus 60 seconds is a correct two-pointer window at amortised O(1) per attempt, but its memory tracks in-window traffic, so one destination in a retry storm holds hundreds of thousands of entries while thousands of quiet destinations hold none.
  2. Use a ring of 60 one-second buckets per destination, each bucket a pair of counters for attempts and failures. On an attempt, advance the ring by the elapsed whole seconds, zeroing at most min(elapsed, 60) buckets, then increment the head. That is amortised O(1) with a fixed footprint per destination.
  3. State the footprint: 60 buckets times two 4-byte counters is 480 bytes of payload per destination, so 40,000 destinations is roughly 20 to 25 MB with per-entry overhead, bounded by the catalogue rather than by the rate. The cost is granularity, since the oldest bucket ages out in whole seconds, which is far tighter than the decision needs.
  4. Require a minimum sample before the circuit may open. A destination with three attempts and three failures reads as 100 percent and is not evidence; a floor of roughly 20 attempts in the window makes the ratio meaningful, and below that floor use a run of consecutive failures as the trigger instead.

Follow-up

  • The fleet is 30 instances and each sees roughly a thirtieth of a destination's traffic. Where does the rate actually live, and what does a per-instance answer get wrong?
  • A destination answers in 9.5 seconds and succeeds. It is not failing but it is consuming your per-destination concurrency. What signal should open the circuit here?

Collapse a redelivered event batch into per-aggregate high-water marks

Easy · hashing · at-least-once · aggregation

You drain a batch of up to 5,000,000 events, each (aggregate_id BIGINT, aggregate_version INT, event_type, payload). The log guarantees order within one aggregate only; the batch merges 64 partitions, and a relay failover has redelivered a range, so an older version for an aggregate can appear after a newer one. Given a map of last_applied_version per aggregate, produce the events worth applying, at most one per (aggregate_id, version), plus the count discarded. Target O(n) time. State the memory for 2,000,000 distinct aggregates and what you do when it does not fit.

Approach

  1. One pass, one hash map from aggregate_id to the highest version kept, and a discard counter. An event whose version is at or below last_applied_version for its aggregate is dropped without further work, which is the whole reason the event carries its version rather than a delta. O(n) expected time, O(d) space in distinct aggregates.
  2. Keep the maximum, never the last occurrence. The redelivered range means the final appearance of an aggregate in the batch can be an older version than one seen earlier in the same batch, so last-wins applies stale state over newer state and the projection regresses with no error anywhere.
  3. Cost the memory instead of calling it large: an 8-byte key plus a 4-byte version is 12 bytes of payload, and an open-addressed table held at a 0.7 load factor costs roughly 17 bytes per entry before per-slot metadata, so 2,000,000 aggregates is tens of megabytes in a native layout and several times that in a runtime that boxes both key and value.
  4. If the distinct set exceeds memory, partition on hash(aggregate_id) mod P and reduce each partition independently. Every event for one aggregate hashes to the same partition, so the per-partition result is exact and the merge is concatenation rather than a second reduction.

Follow-up

  • The payload is a patch rather than a snapshot, so applying only the highest version loses the intermediate changes. What changes in your reduction?
  • How do you detect that version 7 arrived while version 6 was never delivered, and what should the consumer do about the gap?

Find overlapping job attempts and peak concurrency from lease records

Medium · sweep line · intervals · leases

A day of job_run history yields about 50,000,000 attempt records: (job_run_id, job_type, attempt, started_at, finished_at which is NULL when the worker died, lease_expires_at). Leases expire on a clock, so a job that outran its lease ran twice. Produce (a) every job_run_id whose attempts overlapped in wall-clock time and (b) the peak number of simultaneously running attempts per job_type with the minute it occurred. Target O(n log n). State how you treat a NULL finished_at and what clock skew does to your answer.

Approach

  1. Define the interval before sorting anything: an attempt occupies [started_at, COALESCE(finished_at, lease_expires_at)). finished_at is observed and lease_expires_at is only a promise, so every attempt without a finish contributes an estimate and the whole result is a lower bound on overlap rather than an exact count.
  2. For peak concurrency, sweep: emit 2n endpoints, sort by (timestamp, kind) with ends ordered before starts at equal timestamps, then walk the sequence maintaining a counter per job_type and record each type's maximum with its timestamp. O(n log n) dominated by the sort, O(n) space, or O(1) extra if the sort is external and the walk streams.
  3. For overlap detection, do not compare attempts pairwise. A single global sort by (job_run_id, started_at) gives both the grouping and the order; within a group, keep the maximum end seen so far and report an overlap exactly when the next start is less than that running maximum, which is one linear pass after the sort.
  4. Half-open intervals matter and are easy to get wrong: with closed intervals an attempt ending at the same millisecond another begins reads as concurrency two, and across 50,000,000 records that artefact swamps the real signal.

Follow-up

  • A handler is not idempotent and you have found 400 overlapping jobs. Which of them actually caused damage, and what would you query to find out?
  • Peak concurrency for one job_type is 4 against a configured cap of 4. Is the cap working, or is the data hiding attempts that never started?

What is your strategy for managing database schema changes in an DB2 environment?

Medium · System Architecture and Logic

Approach

  1. Start with the IBM i specific risk: changing a file's record format changes its format level identifier, and programs compiled against the old format fail with a CPF4131 level check on open. Turning off level checking with LVLCHK(*NO) hides the mismatch instead of fixing it, so I recompile or shield the callers.
  2. Find every dependant first: DSPDBR for logical files and views over the table, and DSPPGMREF across the application libraries to list programs that use the file natively, so the recompile list is complete before deployment.
  3. Choose the change path by how the file was defined: CHGPF with new DDS source for DDS physical files (data is kept and mapped by field name), ALTER TABLE for SQL tables; add new columns with NOT NULL WITH DEFAULT so existing rows and older INSERTs stay valid.
  4. Shield old programs where a recompile is risky: give them a logical file or view that keeps the old format, and move programs to explicit SQL column lists over time so additive changes stop breaking them.
  5. Treat it as a deployment: scripts in source control, rehearsed on a production-size copy because the change can rebuild a large table and needs an exclusive lock, a save of the file before the change, a run outside batch and interactive peaks, and a written rollback.

Follow-up

  • A program nobody listed hits a level check the morning after deployment. What do you do first, and what do you change in the process?
  • How would you widen a numeric column that many RPG programs read with native I/O?
  • How do you roll back a column change after new data has already been written to it?

Write the update path that detects a concurrent edit

Medium · optimistic concurrency · transactional outbox · audit history

resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.

Approach

  1. One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
  2. Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
  3. State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
  4. Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.

Follow-up

  • A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
  • Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?

How do you integrate RPG programs with modern web services or APIs?

Medium · Technical Proficiency in RPG

Approach

  1. Split the question by direction. Outbound (RPG calls a REST API): use the QSYS2 HTTP SQL functions (HTTP_GET, HTTP_POST) from embedded SQL on releases that have them, or an open-source library such as HTTPAPI. Inbound (others call RPG): expose an ILE program or service program through the Integrated Web Services server, or wrap it as an SQL stored procedure that a Java, Node.js or Python service calls over JDBC/ODBC.
  2. Parse and build JSON with JSON_TABLE and JSON_OBJECT in embedded SQL, or with DATA-INTO plus a parser such as YAJLINTO, mapping into a qualified data structure; say which one you used and why (SQL is built in, DATA-INTO maps nested arrays straight into structures).
  3. Handle character conversion explicitly: IBM i data is EBCDIC and APIs speak UTF-8 (CCSID 1208), so declare CCSIDs on the fields that cross the boundary instead of hoping the default conversion is right.
  4. Design for failure: set timeouts, check SQLSTATE and the HTTP status separately, log request and response with a correlation id, and give each outbound request an idempotency key so a retry after a timeout cannot post the same order twice.
  5. Keep slow calls out of interactive jobs: for high volume or unreliable endpoints, put requests on a data queue or a staging table and let a never-ending batch job send them and record the outcome, so a down partner does not block users.

Follow-up

  • The remote API times out after it may already have processed the request. What does your program do next?
  • Where do you keep API credentials and TLS certificates on IBM i, rather than in the source?
  • How would you expose an existing order-entry program as a REST endpoint without rewriting its logic?

How do you approach the modernization of existing RPG programs without disrupting core business operations?

Medium · System Architecture and Logic

Approach

  1. Inventory before touching code: build a cross-reference of programs, files and callers (DSPPGMREF and DSPDBR to an outfile, then query it), map the batch schedule, and pick a first target that changes often but has few callers.
  2. Modernise in small, reversible steps: convert fixed-format to free-form, replace numbered indicators with named ones (INDDS for display files), and pull subroutines out into subprocedures in a service program with prototypes in a /COPY member.
  3. Protect callers when service programs change: add new exports only at the end of the binder source and keep the old signature as a PGMLVL(*PRV) block, so existing programs do not fail with a signature violation.
  4. Prove equivalence with a parallel run: run the old and new versions against the same copy of production input and compare the output files row by row (for example with SQL EXCEPT both ways) before cutover.
  5. Make cutover and rollback cheap: deploy outside the batch window, keep the previous objects saved or in a separate library so rollback is a restore or a library-list change, and use a control-table or data-area switch where old and new paths must coexist for a while.

Follow-up

  • How do you decide which program to modernise first?
  • What happens to existing callers if you change a service program's parameter list, and how do you avoid it?
  • How do you show the business that the modernised program produces the same results as the old one?

How do you document your code to ensure it remains maintainable for other team members?

Medium · System Architecture and Logic

Approach

  1. Make the code carry most of the meaning: free-form RPG, descriptive names instead of six-character RPG III names, named indicators instead of *IN01 to *IN99, and qualified data structures so a reader can see where a field belongs.
  2. Document contracts where callers look: prototypes in a shared /COPY or /INCLUDE member, and a header on each procedure stating purpose, parameters, return value, files it updates and the errors it can signal.
  3. Comment the why, not the what: the business rule, the client or ticket behind an odd branch, and the units of a field; keep change history in source control instead of a growing comment block at the top of the member.
  4. Document the data and the operations too: LABEL ON and COMMENT ON for tables and columns so the meaning is visible in the catalog, a cross-reference of programs to files, and run notes for each batch job (schedule, inputs, restart point, who to call).
  5. Keep it current through review: a code review checklist item for comments and headers, so the documentation changes in the same change as the code.

Follow-up

  • You inherit a several-thousand-line program with no comments. How do you document it as you learn it?
  • How do you stop documentation from drifting away from the code over time?
  • What would you write down for a batch job so that someone else can restart it after a failure at 3 a.m.?

Describe your approach to testing new features in a production-critical environment.

Medium · System Architecture and Logic

Approach

  1. Test in isolation from production: a separate test library or partition with masked, production-like data, and a library list that points the job at test files, so nothing in the test run can update live data.
  2. Test at two levels: unit tests for subprocedures in service programs with an xUnit framework such as RPGUnit, and a regression run of the affected batch jobs on a copy of production input with the outputs compared to the previous version (SQL EXCEPT both ways shows every changed row).
  3. Cover the cases that only production volumes and calendars expose: month-end and year-end runs, record locks with interactive users updating the same records, commitment control boundaries, and empty or maximum-size inputs.
  4. Release so it can be undone: promote the same compiled objects from test through change management, save the previous objects before deployment, and gate the new behaviour behind a control-table or data-area switch that can be enabled per site or client.
  5. Verify after release: watch job logs and QSYSOPR messages, run reconciliation queries on the first production results, and keep the rollback steps written down until the first full business cycle has passed.

Follow-up

  • The change only affects month-end processing. How do you test it before month-end arrives?
  • What does rollback look like if the release also changed a file's layout?
  • How would you confirm in production that the new feature works without affecting live orders?

Explain your process for debugging complex logic errors in legacy RPG codebases.

Medium · Technical Proficiency in RPG

Approach

  1. Reproduce before theorising: copy the failing input records into a test library, run the program against them with the library list pointed there, and save the job log (DSPJOBLOG) plus any RPG dump so the exact failing record and statement are on paper.
  2. Step through it in a source debugger: compile with DBGVIEW(*SOURCE), then use STRDBG or the RDi debugger; for a submitted batch job, attach with STRSRVJOB or a service entry point, and set watch breakpoints on the field that ends up wrong to find the statement that changes it.
  3. Check the usual legacy suspects first: numbered indicators set in one subroutine and tested far away, global fields reused across subroutines, MOVE/MOVEL truncating or padding, and fixed-form ADD/Z-ADD dropping high-order digits under the default TRUNCNBR(*YES), where EVAL would raise an overflow error instead.
  4. Confirm the object matches the source you are reading: DSPOBJD with DETAIL(*SERVICE) shows the source member and its change date, and a stale compile explains many 'impossible' bugs.
  5. Before fixing, find the blast radius with DSPPGMREF and DSPDBR (who else reads or updates the same files), then write the fix as a small change plus a rerun of the failing records, so the defect and its regression check are kept together.

Follow-up

  • The bug only appears in the overnight batch run and never interactively. How do you debug it?
  • How do you find which program is writing a bad value into a file field when many programs update that file?
  • After the fix, how do you show you did not break the other programs that use the same subroutine or file?

Suggested practice checklist

The plan follows the two reported rounds and the reported question groups: RPG and file I/O, debugging and refactoring, integration and modernization, batch tuning and testing, then behavioral stories. Practice-library drills are used only as adjacent practice.

Day 1 — Inventory your RPG and IBM i experience

  • List the programs and projects you can discuss, noting RPG version style (fixed-format, RPG IV, free-form), your own contribution and the outcome.
  • List the IBM i utilities and debugging tools you use, with one sentence on a problem each one helped you solve.
  • Write and rehearse aloud a short answer to the question about your experience with different RPG versions.

Deliverable: An experience inventory of projects and tools, plus a spoken answer to the RPG versions question.

Day 2 — File I/O and DB2 schema changes

  • Write the same task twice: a native I/O loop with CHAIN, READE and UPDATE, and a single embedded SQL statement. Note when each is the better choice.
  • Outline a schema change plan for a DB2 table: add a nullable column, backfill, switch programs over, retire the old field, and say how dependent logical files and programs are found.
  • Rehearse the file I/O answer aloud, including locking and commitment control.

Deliverable: A side-by-side native versus SQL example, a written schema change plan, and a spoken file I/O answer.

Day 3 — Debugging legacy logic and refactoring

  • Write your debugging sequence as numbered steps: reproduce, narrow, inspect data and the call stack, fix, run regression checks. Attach it to one real bug you fixed.
  • Sketch how you would split a monolithic program into sub-procedures in a service program, and how you would prove output is unchanged.
  • Work the adjacent practice drill on writing an update path that detects a concurrent edit, to practise the record-locking discussion.

Deliverable: A numbered debugging sequence, a refactoring sketch, and a worked concurrent-edit solution.

Day 4 — Web service integration and modernization

  • Outline an integration between an RPG program and a web service: caller, payload format, error handling, and what happens on a retry after a timeout.
  • Write an incremental modernization plan for one program you know: what you extract first, how old and new run side by side, the cutover and the rollback.
  • Work the adjacent practice drill on collapsing a redelivered event batch, to practise making retries safe.

Deliverable: A written integration outline, a modernization plan with cutover and rollback, and a solved retry-safety drill.

Day 5 — Batch performance and production testing

  • Write your batch optimization story: baseline, bottleneck, change, verification of identical output, and results.
  • Outline a test approach for a new feature in a production-critical environment: separate test libraries, representative data, regression comparison and a staged release with rollback.
  • Work the adjacent practice drill on overlapping job attempts and peak concurrency to practise reasoning about parallel batch work.

Deliverable: A finished batch optimization story, a test plan outline, and a solved concurrency drill.

Day 6 — Documentation and stakeholder stories

  • Write down your documentation habits: program header purpose and change history, procedure interface comments and decision notes. Bring one real example.
  • Write a tight-deadline story with the ranking you applied and what you deferred.
  • Write a technical-constraint story that opens with date, cost and risk, and rehearse it aloud.

Deliverable: A documentation example plus two rehearsed stories, one on deadlines and one on explaining a constraint.

Day 7 — Full spoken run-through of both rounds

  • Answer the motivation question aloud, using specific reasons and a skill you are adding next.
  • Run a screening pass: RPG versions, file I/O, and your IBM i tools, each in under a minute or so of speaking.
  • Run a technical-discussion pass: debugging, refactoring, migration data integrity, integration and modernization, speaking your method for each.

Deliverable: A recorded or written self-review that lists the answers still vague and the one real example you will use for each.

Behavioral preparation for an IBM i role

The reported behavioral prompts concern RPG experience, file work, batch tuning, deadlines, explaining constraints and staying with the IBM i platform. Strong answers use a real maintenance episode with a stated outcome and show the trade-off you made.

Can you describe your experience working with different versions of RPG (e.g., RPG IV, Free-form RPG)?

Medium · Technical Proficiency in RPG

Approach

  1. Organise the answer by generation, not by years: older fixed-format programs with the program cycle and numbered indicators, RPG IV under ILE with procedures and modules, and free-form calculations or fully free-form source. For each, say what you actually wrote, fixed or reviewed.
  2. Include one concrete story, such as converting fixed-format calculations to free-form, replacing indicators with named conditions and built-ins like %found and %eof, or moving a subroutine into a procedure in a service program. State how you proved the output was identical before and after.
  3. Be honest about the weaker side. If you mostly write in one style, say so and explain how you read the other, since maintenance work means opening code in every style.
  4. Close with a judgement call: when you convert a program fully and when you leave stable fixed-format code alone and change only the lines a fix needs, because the risk of conversion is real.

Follow-up

  • How do you replace indicators when converting to free-form without changing behaviour?
  • What does ILE let you do that the original program model did not?
  • How did you verify that a converted program produced exactly the same output?

How do you handle file I/O operations and data manipulation in an IBM i environment?

Medium · Technical Proficiency in RPG

Approach

  1. Split the answer into two access styles: native record-level I/O (file declared in the F-spec, CHAIN for a keyed lookup, SETLL plus READE for a key range, WRITE, UPDATE, DELETE, tested with %found, %eof and %error) and embedded SQL for set-based work.
  2. Say how you choose. Keyed single-record lookups and screen-driven programs suit native I/O. Bulk filtering, joins and aggregation suit one SQL statement, because a loop that does a CHAIN per row spends its time on repeated calls.
  3. Cover data correctness: externally described files and data structures so field definitions come from the file, packed versus zoned decimal handling, date fields, null handling in SQL, and explicit I/O error handling instead of letting a program halt.
  4. Cover concurrency: update locks held on a record, what your program does when another job holds it, and commitment control with journaling when several files must change together so a partial update rolls back.

Follow-up

  • For an update touching millions of rows, would you use native I/O or SQL, and why?
  • What does your program do when READE hits a record locked by another job?
  • How do you make an order header and its lines update together or not at all?

Describe a time you optimized a batch processing job that was underperforming.

Medium · Technical Proficiency in RPG

Approach

  1. Open with the situation in two sentences: what the job did, what depended on its output, and why slow was a problem. Use your own real numbers for runtime and volume and do not round them up.
  2. Describe measurement before any change: elapsed time per step from the job log, then the step that dominates. Look for a per-record CHAIN or SQL statement inside a loop, and check whether the query used an index or scanned the table, using Db2 for i plan analysis or index advice.
  3. Name the specific change and why it helps: a set-based SQL statement in place of a row loop, a new or adjusted logical file or index for the access key, removing repeated lookups from the inner loop, reading in key order, or splitting the work into parallel jobs by key range.
  4. Prove the result: record counts and control totals matched, before and after runtimes on comparable volume, and a rollback route because it ran in production. The classic mistake is saying you made it faster with no baseline, or tuning a step that was not the bottleneck.

Follow-up

  • How did you know that step was the bottleneck?
  • If you split the work across parallel jobs, what stops two jobs touching the same keys?
  • How did you confirm the output was identical to the old job's?

How do you handle tight deadlines when managing multiple development requests?

Medium · Behavioral and Professionalism

Approach

  1. Choose a real episode with several competing requests and state the pressure in a sentence or two: what was due, who was asking, and what depended on it.
  2. Show your triage mechanism: list every request, rank by business impact and deadline, estimate each, and spot dependencies such as two requests touching the same program or file. Then tell requesters what will slip instead of quietly working longer.
  3. Say what you protected and what you cut. In a production-critical environment, testing and code review stay; scope, nice-to-have enhancements or secondary requests get deferred or split into phases, with the requester agreeing to it.
  4. Finish with the outcome and what you would change: what shipped when, what was renegotiated, and any follow-up you scheduled so a quick fix did not become permanent. A story about heroics and overtime with no prioritisation misses the point.

Follow-up

  • Two managers each say their request is the top priority. What do you do?
  • What did you drop, and who agreed to that?
  • How did you stop the quick fix from becoming the permanent version?

Describe a situation where you had to explain a technical constraint to a non-technical stakeholder.

Medium · Behavioral and Professionalism

Approach

  1. Choose a constraint with a real business consequence on this stack, such as a field-length change that ripples through files and programs, a batch window that cannot absorb a new step, record locking that blocks a requested feature, or a reason an integration cannot be real-time. Use one you handled.
  2. Lead with what the stakeholder cares about: date, cost, risk and what they can still have. Put the mechanism second, in one plain sentence or one analogy from their world, not in RPG or DB2 terms.
  3. Present two or three options with their trade-offs and a recommendation, for example do it now with a downtime window, phase it, or use a workaround with a stated limit. Candidates report that explaining risks and benefits clearly is part of the role.
  4. Close the loop: how you confirmed they understood (they restated the impact or made a decision), what was chosen and what happened. The mistake that sinks it is a story where you used jargon or simply said no.

Follow-up

  • What did you do if the stakeholder insisted on the original request anyway?
  • How did you check they understood the risk, not just the date?
  • What would you explain differently next time?

What motivates you to continue working within the IBM i ecosystem?

Medium · Behavioral and Professionalism

Approach

  1. Give specific reasons drawn from your work instead of nostalgia: logic that runs the same business process reliably year after year, an integrated database and object model, code that maps directly to orders, inventory or shipments, or the satisfaction of modernizing carefully.
  2. Back each reason with one example, such as a program you kept stable through a change, a modernization you led, or a class of problem you enjoy on this platform.
  3. Show forward motion. Candidates report that interest in modernizing these systems is worth showing, so name what you are building alongside RPG, such as free-form style, ILE modularity, SQL, or calling and exposing web services.
  4. Avoid disparaging other stacks and avoid sounding as if you stayed because it is all you know. State a choice and a direction.

Follow-up

  • How would you answer a colleague who wants everything moved off the platform?
  • Which parts of the platform would you leave unchanged, and why?
  • What skill do you want to add next alongside RPG?