cswork / libraryOpen practice workspace

Interview guides · BETWEEN

BETWEEN Software Engineer Interview Guide

BETWEEN Software Engineer interview guide: Angular and front-end prep, the take-home, client-facing questions, and a 7-day plan with answer outlines.

The 60-second brief

Candidates describe BETWEEN as a company that works as a partner to several clients, so engineers are placed on client projects rather than on a single in-house product. The work reported for this role ranges from front-end heavy tasks to wider system implementation, depending on the assignment. Angular is the framework named in candidate reports, and the stack changes from one client to the next. Day to day, engineers turn business needs into technical requirements, write and maintain code, join stand-ups and sprint planning, review code and document what they build.

This guide is for engineers interviewing for a Software Engineer position at BETWEEN, especially on front-end or Angular-flavoured assignments. It covers the process candidates report (recruiter screen, technical assessment, client meeting), the six reported questions on past work, debugging, maintainability, code review, learning quickly and explaining technical ideas, and a seven-day plan to rehearse them.

Candidates report a recruiter screen, then a technical assessment that may be a take-home assignment or a technical conversation, and finally a meeting with the client. Overall timelines are reported as a few weeks.

Focus areas

  • Angular
  • Front-end development
  • Technical interview (work assignment / take-home)

Overview

The reported work is project delivery for clients. Engineers translate business needs into technical requirements, write and maintain code, join stand-ups and sprint planning, take part in code reviews and keep documentation current. Assignments vary: some are front-end heavy, others touch broader system implementation. So preparation is less about one algorithm and more about being able to explain what you built, why you built it that way, and how you would work inside someone else's codebase.

The topics candidates associate with this loop are Angular, front-end development, a work assignment or take-home, and technical screening questions about past work. The reported questions are conversational: a walk-through of your experience with a framework, production debugging, keeping code maintainable and scalable, how you review code, learning a technology under a deadline, and explaining a technical idea to a non-technical person. Prepare real projects with specifics (structure, decisions, trade-offs, bugs) rather than definitions.

Communication carries unusual weight here because the engineer represents the company in front of a client. Candidates report that clear, proactive updates, honesty about your experience level, a check on professional English or the client's language, and the ability to join an existing team and pick up legacy code all matter. Practise saying things out loud in the language you will interview in, and keep two or three questions ready about the project, the team and the client.

Where to focus your preparation

Candidates describe a general journey rather than named rounds: a recruiter screen, a technical assessment, and a client meeting. The single entry below covers all of it, so confirm with your recruiter which stages apply to your assignment.

Preparation focus

Candidates report that the process starts with a recruiter screen about your profile and interests, moves to a technical assessment that can be a take-home assignment or a technical conversation, and ends with a meeting with the client. The same candidates say the take-home is a major decision factor and should be started as soon as it arrives, and that some processes include a check of your English or the client's language. Approach it as three conversations about the same thing: your real experience. Prepare a short account of your last two or three projects, a clean small deliverable for the assignment, and calm, specific answers about how you communicate with clients and teammates.

What to demonstrate

  • How accurately you describe your own experience level and projects, including the architecture and the reasons behind your choices
  • Working knowledge of your main framework (Angular is the example reported) and of front-end fundamentals
  • Whether a take-home solution is readable, sensible and easy for someone else to pick up
  • Professional communication: clear updates, listening, composure, and ability to explain ideas to non-technical people

How to prepare

  • Write a one-page walk-through of two or three projects: your role, the stack, how the code was organised, one decision and why you made it
  • Rehearse the technology walk-through, the production debugging question, and the maintainability and code review questions aloud
  • Build a small front-end feature end to end in your main framework with a short README, so the take-home format is familiar
  • Ask the recruiter which stages apply, whether the assignment is a take-home or a conversation, which language the client meeting uses, and whether the project is remote or hybrid

Where candidates lose points

Answering the framework walk-through with a list of buzzwords instead of a project

Anchor the answer in one real project: what it did, your role, how the code was structured, and one decision with its reason. Only mention features you can explain further.

Treating the take-home as a chance to show off clever code

Candidates report that clean, readable solutions are valued over complex ones. Use clear naming, small components, a few tests and a README that states your decisions and what you would do next.

Being vague about your experience level in the recruiter screen

Prepare a precise summary of what you have shipped, with which versions and for how long. Candidates report that unclear communication of experience at this stage is a common cause of a negative outcome.

Telling team stories where your own contribution is invisible

For the learning-quickly and explaining-to-a-stakeholder stories, state what you personally decided and did. Credit the team, but make your actions the centre of the story.

Jumping straight to a fix when asked about production debugging

Describe a sequence: reproduce the issue, check what changed recently, read logs and the browser network and console, narrow the cause, fix it, then add a test or alert to prevent a repeat.

Questions & practice

Diff a projection against the primary without per-row point reads

Hard · reconciliation · range hashing · throttling

The listing projection has drifted and some rows show a stale version. The primary holds 40,000,000 resource rows across 12,000 tenants while serving 1,200 writes and 14,000 reads per second. The obvious repair, reading each resource row and comparing its version against the projection, is correct and would eventually finish. Explain precisely why it is unacceptable here, then give a diff that finds the differing rows, state its complexity, and make it safe to run against a live primary. Replication lag is usually under 100 ms and is not bounded.

Approach

  1. Quantify the naive cost rather than calling it slow: 40,000,000 point reads at even 0.5 ms each is over five hours serialised, and the only lever is concurrency, which is exactly what you cannot spend. The primary's pool is sized for the write path, and 40,000,000 random reads evict the buffer cache that sustains the 85 percent cache hit rate, so the audit degrades the system it is auditing.
  2. Replace random access with one ordered pass per side. Both sides can be read in (tenant_id, resource_id) order, which is a sequential scan on each and a merge join in O(n) time and O(1) memory. For a dense diff that is the whole answer, and it reads the primary once instead of 40,000,000 times.
  3. For the expected sparse case, compare range hashes instead of rows: partition the key space, compute per range an order-independent aggregate over hash(resource_id, version), compare aggregates, and descend only into ranges that differ. With d differing rows and branching factor B, at most d ranges mismatch per level, so the drill-down examines O(d log_B(n/d)) ranges and reads full rows only in mismatching leaves.
  4. Aggregate with a sum modulo 2^64 or a multiset hash, never XOR. XOR is order-independent but self-cancelling, so two rows wrong in the same way, or a row duplicated on one side, leave the range aggregate matching and the range is declared clean.

Follow-up

  • The diff reports 900 stale rows. How do you decide between patching those rows and rebuilding the projection from resource_revision?
  • Same job, but the projection lives in a search index that cannot be scanned in key order. What changes?

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?

Merge partitioned event streams into one ordered feed with bounded lateness

Hard · k-way merge · watermarks · out-of-order streams

The read-model service consumes 64 log partitions carrying about 4,000 events per second in total. Each partition is ordered within itself, but partitions drift by up to 30 seconds, and the activity feed must present a tenant's events in occurred_at order. Produce the merge. State its complexity, the buffer it requires in events and in bytes, what happens when one partition is idle, and what you do with an event that arrives after you have already emitted its position. Payloads average 1 KB.

Approach

  1. Merge with a min-heap over the 64 partition heads keyed on (occurred_at, event_id): O(log P) per event and O(n log P) overall. The tie-break on event_id is what makes the output deterministic when two partitions carry the same millisecond, which matters because the feed is paginated and a non-deterministic order reorders pages under the reader.
  2. Emitting the heap head is only correct once every partition has produced everything up to that timestamp, so the emit condition is a watermark: the minimum across partitions of the highest occurred_at seen, less the allowed lateness. Events are held until the watermark passes them, which is what turns individually ordered streams into a jointly ordered one.
  3. Size the buffer from the lateness rather than guessing: 4,000 events per second times 30 seconds is 120,000 buffered events, and at 1 KB each about 120 MB of heap. That number is the real price of the ordering guarantee and belongs in front of whoever asked for it.
  4. Handle the idle partition explicitly, because it fails the feed rather than corrupting it: a partition with no traffic never advances its own maximum, so the watermark freezes and output stops entirely. Either every partition emits a periodic idle marker carrying the broker's current time, or the watermark falls back to wall clock for a partition silent beyond a threshold.

Follow-up

  • The lateness budget is raised to five minutes. What is the new buffer, and what besides memory changes?
  • The consumer restarts. Where does it resume from, and what does the feed look like for the first 30 seconds?

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?

Find version gaps and relay lag with window functions

Medium · window functions · event tables · frame semantics

outbox_event holds event_id, aggregate_type, aggregate_id, aggregate_version, event_type, payload, status ('pending','published','dead'), attempts, created_at, published_at. A projection is missing rows and you must decide whether the relay skipped events or the consumer dropped them. Write three queries over the last seven days: one listing every aggregate_id whose published aggregate_version sequence has a hole, one giving per-day counts with a running total, and one returning the newest published event per aggregate. For each, say where the window function is evaluated relative to WHERE and LIMIT. PostgreSQL 16.

Approach

  1. Gaps: compute lead(aggregate_version) OVER (PARTITION BY aggregate_id ORDER BY aggregate_version) in a subquery, then filter next_version <> aggregate_version + 1 in the outer query. Window functions are evaluated after WHERE, GROUP BY and HAVING and before the outer ORDER BY and LIMIT, so the predicate cannot sit in the same WHERE clause and PostgreSQL 16 has no QUALIFY.
  2. Say what the seven-day filter does to the answer: it truncates every partition, so the first row per aggregate has no predecessor inside the window and a hole spanning the boundary is invisible. Widen the window, or join to resource.version as the authority for the true maximum.
  3. Running total: SELECT date_trunc('day', created_at) AS d, count() AS n, sum(count()) OVER (ORDER BY date_trunc('day', created_at) ROWS UNBOUNDED PRECEDING). An aggregate inside a window call is legal because grouping runs before windowing. The grouping key is unique per row here so ROWS and RANGE agree, but write the frame anyway — over ungrouped rows with tied timestamps the default RANGE frame pulls in every peer row and the total jumps.
  4. Newest per aggregate: DISTINCT ON (aggregate_id) ... ORDER BY aggregate_id, aggregate_version DESC is the cheap PostgreSQL-only form when an index matches that order; row_number() OVER (PARTITION BY aggregate_id ORDER BY aggregate_version DESC) = 1 is the portable form and needs a subquery for the same evaluation-order reason as the gap query.

Follow-up

  • Relay failover redelivers events. Does a duplicate break the gap query, and how would you detect one from this table alone?
  • Turn the gap check into a continuous monitor rather than a query someone runs after an incident. What does it watch?

How do you ensure your code is maintainable and scalable?

Medium · Technical and Domain Proficiency

Approach

  1. Separate the two goals: maintainable means the next engineer can change the code safely, and scalable means it holds up as load, data and the team grow. Give one concrete practice for each, with an example from a real project and the reason behind it.
  2. Structure: single-responsibility modules with clear boundaries. In Angular, keep components presentational and move data access and business logic into injectable services. Dependency injection lets those services be swapped for mocks in tests, and lazy-loaded feature routes keep the initial bundle small.
  3. Safety net: TypeScript strict mode, ESLint and unit tests on business logic, all run in CI on every pull request, so a refactor is cheap and regressions are caught before merge.
  4. Front-end scaling specifics: OnPush change detection with immutable inputs; trackBy on *ngFor (or track on @for) so a list update does not re-render every row; the async pipe or takeUntilDestroyed so subscriptions do not leak; paginated or virtualised long lists. Profile before optimising.
  5. Trade-off: avoid speculative abstraction. Add a layer only once a second real use appears, and record significant decisions (for example in short architecture decision records) so the why survives team changes.

Follow-up

  • Show me code from a past project you would refactor today. What would you change, and why?
  • As an Angular app grows, how do you manage shared state: services with RxJS or signals, or a store such as NgRx? What decides it?
  • How do you know whether an abstraction has paid for itself?

What is your process for reviewing code and providing constructive feedback?

Medium · Technical and Domain Proficiency

Approach

  1. Order of review: read the ticket or pull request description to understand the intent, then check correctness and design, then tests, then readability. Leave formatting to Prettier and ESLint in CI so reviews do not turn into style arguments.
  2. What to check concretely: edge cases and error paths, missing tests for the changed behaviour, changes to public interfaces, performance hot spots such as repeated HTTP calls in a loop, and security. In Angular, flag any bypassSecurityTrust* call, because it switches off the default sanitisation of values bound to innerHTML.
  3. Form of feedback: comment on the code, not the author. Mark severity (blocking versus nit or suggestion), explain why something matters and offer an alternative, ask a question when unsure, and name specific things that were done well.
  4. Keep the process moving: ask for small, focused pull requests, review promptly, move a long comment thread to a quick call and record the outcome in the PR. Non-blocking improvements go into a follow-up ticket rather than holding the merge.
  5. Show the other side too: explain how you handle review comments on your own code, including when you push back with evidence and when you accept the change.

Follow-up

  • Tell me about a review where you and the author disagreed. How was it resolved?
  • What do you do with a very large pull request you cannot review well?
  • How do you review code from a team whose conventions differ from yours, or give feedback to a more senior engineer?

How do you handle complex debugging or troubleshooting in a production environment?

Medium · Technical and Domain Proficiency

Approach

  1. Contain before diagnosing: check the blast radius (error rate, which users or endpoints are affected) and decide whether to roll back or switch the change off behind a feature flag. Restore service first, then look for the root cause.
  2. Build the timeline: what changed just before the first occurrence (deploys, config, dependency versions, data, traffic shape). Follow one failing request end to end using a correlation or request ID across logs and services.
  3. Reproduce with the smallest failing input: capture the request payload or user steps and replay them in staging with production-like config. For a front-end bug, de-minify the stack trace with source maps and check the browser console and network tab for the failing call.
  4. If the cause is still unclear, narrow it systematically: git bisect between the last good and first bad release takes O(log n) builds. When it cannot be reproduced, add targeted logging or tracing behind a flag instead of guessing in production.
  5. Close the loop: ship the fix with a regression test that fails without it, add the alert or metric that would have caught it sooner, write a blameless postmortem and send clear status updates to stakeholders throughout.

Follow-up

  • The bug only shows up under production load and never in staging. What do you suspect (race conditions, connection-pool exhaustion, timeouts) and how do you confirm it?
  • When do you roll back, and when do you fix forward?
  • Only some users' browsers hit the error. How do you narrow down the cause?

Suggested practice checklist

The plan follows the reported journey: confirm the process, refresh Angular and front-end fundamentals, rehearse a take-home, practise the technical and behavioral questions aloud, then run a full mock. Days that practise reported questions list them.

Day 1 — Confirm the process and inventory your projects

  • Write the questions to send your recruiter: which stages follow the screen, whether the technical step is a take-home or a conversation, which language the client meeting uses, and whether the project is remote or hybrid.
  • Write a one-page sheet for each of two or three projects: your role, the stack, how the code was organised, one decision and its reason, one bug you fixed.

Deliverable: A list of questions for the recruiter and a project sheet for each of your two or three main projects.

Day 2 — Refresh Angular and front-end fundamentals

  • Review the concepts you will be asked to explain: components and templates, dependency injection, lazy-loaded routing, reactive forms, RxJS with the async pipe, and change detection. If your main framework is React, cover hooks, state and effects instead.
  • Explain each concept aloud in two or three sentences as you would to an interviewer, then give your technology walk-through answer.

Deliverable: A one-page cheat sheet in your own words and a recorded or spoken walk-through of your experience with your main framework.

Day 3 — Rehearse a take-home

  • Build a small feature end to end: a searchable, sortable list backed by a mock API, with loading, empty and error states.
  • Favour readable structure over cleverness: small components, clear names, a few unit tests.
  • Write a short README with your decisions and what you would improve with more time.

Deliverable: A small repository with working code, tests and a README.

Day 4 — Production debugging, maintainability and code review

  • Write a step-by-step approach for a production front-end bug: reproduce, check recent releases, read the console, network and logs, narrow down the cause, fix, then add a test or alert.
  • Write your checklist for keeping code maintainable and scalable, with an example from a real project.
  • Outline how you review code and give feedback, including how you phrase a critical comment.

Deliverable: Three half-page outlines: debugging sequence, maintainability checklist and code review process.

Day 5 — Write and rehearse behavioral stories

  • Write a story for learning a technology quickly under a deadline, with the learning plan, the quality guard and the result.
  • Write a story for explaining a technical concept to a non-technical stakeholder, with the decision it led to.
  • Write a third story about joining an existing team or picking up legacy code, then say all three aloud.

Deliverable: Three written stories with your own actions highlighted, each rehearsed aloud once.

Day 6 — Client-facing communication

  • Practise a status update that covers what is done, what is next, what is blocked and what is at risk.
  • Record yourself explaining the architecture of one past project in the language of your client interview.
  • Write two or three questions to ask about the project, the team and the client.

Deliverable: A status update template, a recording of your architecture explanation and your list of questions.

Day 7 — Full mock

  • Run a mock in the reported order: a short profile introduction for the recruiter, technical questions on your framework experience, debugging, maintainability and code review, then the behavioral stories.
  • Review the answers where you hesitated, fix them, and send a brief thank-you message if you have a real interview coming.

Deliverable: A completed mock and a short list of answers to tighten.

Client-facing behavioral preparation

Candidates describe the soft-skill portion as covering communication, active listening, composure under pressure, handling feedback from non-technical managers and joining an existing team, including picking up legacy code. The first three prompts are reported questions; the last two cover areas candidates describe.

  1. Tell me about a time you joined an existing team and had to pick up legacy code.
  2. Tell me about a time a non-technical manager gave you feedback you disagreed with.

Can you walk us through your experience with [Specific Technology, e.g., Angular or React]?

Medium · Technical and Domain Proficiency

Approach

  1. Choose one or two real projects in the framework and tell them as a walk-through: what the application did, which part was yours, how the code was organised (components or modules, routing, where state lived, how data was fetched), then one decision and the reason behind it. Candidates report that the why matters as much as the how.
  2. Name framework concepts you actually used and can defend. For Angular that might be components and services wired through dependency injection, lazy-loaded routes, reactive forms, RxJS streams consumed with the async pipe, and OnPush change detection. For React it might be hooks, lifting state, memoisation and a data-fetching layer. Skip anything you only read about.
  3. Cover quality, not only features: how the code was tested (unit and component tests), how it was built and released, and one concern such as bundle size, accessibility or form validation that you handled.
  4. Be exact about your edges: which version you used, which parts you owned and which you only consumed, and what you have not touched. Candidates report that stating your experience level clearly in the early screen matters.
  5. Finish with what you would change now, such as moving shared state out of components or splitting a large module. It shows judgement and keeps the walk-through from sounding like a CV recital.

Follow-up

  • How does that framework decide when to update a view, and how did you cut down unnecessary updates in your project?
  • Where did you keep shared state and why there rather than in a service, store or parent component?
  • What was the hardest bug in that project and how did you find it?

Describe a time you had to learn a new technology quickly to meet a project deadline.

Medium · Technical and Domain Proficiency

Approach

  1. Use a tight STAR shape with most of the time on action: two sentences on the deadline, what was unfamiliar and what was at stake, then a concrete learning plan rather than 'I read up on it'.
  2. Show the method: scope down to the smallest slice the deadline required, read the official documentation, build a throwaway spike before touching the real feature, read how existing code in the project did it, and write tests early so progress was checkable.
  3. Show the quality guard. Explain how you avoided shipping something you did not understand: a review from a teammate who knew the technology, a limited first release, and an early heads-up to the project lead or client about the remaining risk. Candidates report that transparent updates matter.
  4. Give a concrete result: what shipped, what you deliberately cut or deferred, and what you went back to learn properly afterwards.
  5. Do not claim mastery in a few days. The weak version is a hero story with no mistakes; the strong version names one thing you got wrong first and how you caught it.

Follow-up

  • What did you decide not to learn at that point, and did it cost anything later?
  • What did you get wrong at first, and how did you discover it?
  • How did you tell your lead or the client about the risk while you were still learning?

Tell us about a time you had to explain a technical concept to a non-technical stakeholder.

Medium · Behavioral and Soft Skills

Approach

  1. Pick one real concept and one real audience, for example a client contact or project manager who needed to decide something. Open with the decision they faced and why the explanation was needed, so the story has a purpose.
  2. Show the translation. Start from their goal, replace jargon with a plain analogy or a small concrete example (a quick demo, a diagram, a before and after), and state the consequence in their terms: cost, risk, delivery date or user impact.
  3. Show that you checked understanding: you asked them to say it back, watched for the decision they made, or followed up in a short written summary.
  4. Include a moment of pushback or confusion and how you stayed calm and adjusted your explanation instead of repeating it louder. Candidates report that composure under pressure and handling feedback from non-technical managers are part of the evaluation.
  5. Avoid stories where you only simplified a topic and nothing followed, or where the stakeholder comes across as unable to understand. The outcome should be a decision, a changed plan or a shared understanding.

Follow-up

  • What would you have done if they still disagreed after your explanation?
  • How do you respond when the honest answer is that you do not know yet?
  • How would you explain the same concept in writing, in the client's language, to someone who cannot ask follow-up questions?