skip to content

Getting At Rows and Columns

Naming the part of a table you want, by label, by position, by condition or by the order you put it in first, and the seam underneath: whether what came back is a window or storage of its own.

on this pageshow

questions

26

When a table is reordered, which of a row label and a row offset still names the same record, and why?

level: juniorimportance: must knowfreq 74%

answer

  1. two names for the same row
  2. identity against coordinate
  3. one survives reordering, the other relabelling
  4. the row carries its label with it
  5. a stale offset still resolves

basics

~20 s

The row label still names the same record; the offset does not. A label is an identity the row carries with it, while an offset only describes where the row happens to sit right now.

solid answer

~40 s

Two addressing schemes reach the same rectangle. Addressing by label names a row by what it is called, so the reference survives a reordering and breaks only if the labels themselves are rewritten. Addressing by offset names a row by how far down it currently sits, so it survives a relabelling and breaks the moment the rows move — a reorder, a removal, an insert. Neither scheme is more correct; they answer different questions, and the mistake is not picking the wrong one but not noticing there was a choice. Designs differ in how you ask: some expose two separately named addressing surfaces, some overload a single subscript and infer the scheme, and an unlabelled rectangle of numbers has no labels at all, so an offset is the only name a row there has.

go deeper

for a junior

Recall the one-line distinction and be able to say it without hedging: a label names what the row is, an offset names where it currently sits. Knowing which of the two survives a reordering is the whole of the expected answer.

for a middle

Explain the mechanics: why a stale offset resolves successfully instead of failing, what a removal does to the numbering of the survivors, and what changes when a design offers one overloaded subscript instead of two named surfaces.

for a senior

Show the production judgment. Name the steps that invalidate an offset between derivation and use, say why the silent wrong record is worse than a reference that cannot resolve, and describe how you would prove which record you actually got.

for a principal

Frame it as a contract rather than a preference: where offsets are permitted in a codebase, what must never cross a step boundary as a position, and what class of silent failure the rule buys you against the readability it costs.

## Two names for one row A rectangle of data with named columns can carry one further piece of structure: a **row label**, a value identifying the row itself independently of where the row sits. Where that structure exists, every row can be reached two ways, and the two are not two spellings of one idea. - **Addressing by label** names a row by what it is called — "the record labelled `4471`". The label is carried by the row, like a serial number stamped on a part. - **Addressing by offset**, equivalently by position, names a row by how far down it currently sits — "the fourth row from the start, in whatever order the table is in right now". A label is an **identity**. An offset is a **coordinate**. Every behavioural difference between the two schemes follows from that one sentence. ## What each reference survives | what happens to the table | reference by row label | reference by offset | |---|---|---| | the rows are put in a different order | names the same record | names a different record, silently | | some rows are removed | names the same record, or fails to resolve if that record went | still resolves; names a different record | | a row is inserted above it | names the same record | names a different record | | the row labels are rewritten | may no longer resolve | completely unaffected | Read the table by column and the slogan falls out: **a label survives a reordering, an offset survives a relabelling.** Neither survives both. ## Why the offset failure is the dangerous one When a label reference fails, it usually fails audibly: the record is gone and there is nothing to hand back. Designs differ in how they say so — some raise, some hand back a row of absent values, some return an empty result — but none of them quietly gives you a different record. A stale offset does exactly that. As long as the number is inside the current row count the request succeeds and returns a row: a real row, of the right shape, with plausible values. Nothing downstream can tell it from the intended one. Three things routinely make an offset stale between the moment it is derived and the moment it is used: 1. A reordering step is added upstream, perhaps by someone else, perhaps for an unrelated report. 2. Rows are restricted away, so the survivors are renumbered from the start. 3. The source grows or shrinks between runs, so an offset chosen from last week's output lands somewhere else this week. ## The designs do not agree on how you ask This is the part that does not travel between ecosystems, so state it rather than assume it. - Some labelled designs expose **two separately named addressing surfaces**, one per scheme. The surface you call states which scheme you meant and nothing is inferred. - Some expose **one overloaded subscript** and infer the scheme from what is inside it. That is fine until the row labels are themselves integers, at which point the same expression can address a different row depending on data nobody looked at. - **An unlabelled rectangle of numbers has no labels at all**, so an offset is the only name a row has. Code written against it cannot say "the record called 4471" and must carry an identifier in a column of its own. - Some grammars discourage row labels entirely and expect you to restrict rows by a condition over a column you nominate as the identifier, so the label-against-offset question is settled by convention rather than by the tool. ## When an offset is the right answer "Always address by label" is too strong, and an interviewer will push on it. An offset is exactly right when the question really is about position in an order you just imposed yourself: - the first n rows after an ordering step performed in the same expression; - a sample, a chunk boundary, or the head of a file used to eyeball the data; - pairing two sequences that are matched by position and have no labels to match on. The common thread is that the offset is derived and consumed with no step in between that could reorder or restrict. **An offset is a short-lived name.** ## The habit to demonstrate Say which question the reference is asking. If the answer is "that specific record", the reference must be a label — or a value in a column you treat as the identifier — and it must be carried across step boundaries as such. If the answer is "wherever the tenth row happens to be right now", an offset is correct, and it should be computed at the point of use: never stored, never handed to another step, and never written into a report as though it named something durable.

  • What happens to each scheme when rows are removed from the middle of the table?
    The surviving rows keep the labels they had, so the set of labels is simply non-contiguous and every surviving label still names its own record. Positions are recomputed from the start, so every offset after the removal point now names a different row than it did — and it still resolves, which is why the breakage is silent.
  • A rectangle of numbers carries no row labels. How do you write a durable reference to one of its rows?
    You cannot do it with an address at all, because the only address is the offset and the offset is not durable. You carry an identifier as a value — a column of keys alongside the numbers, or a separate sequence of identifiers matched by position — and re-derive the offset from that identifier at the point of use.

A row label is the catalogue number printed inside a book; an offset is "third from the left on that shelf". Reshelve the section and the catalogue number still finds the book, while the position now finds someone else's.

saying these in an interview costs you the question

  • Says the two schemes are interchangeable, just different syntax for one thing.
  • Believes an offset reference is stable because the underlying data did not change.
  • Thinks a label reference stops working once the table has been sorted.
  • Assumes every rectangle of values carries row labels, so offsets are never needed.
  • Counts the first row as row one in every host without checking the convention.
open as a page

In a zero-based host, rows 2 through 5 are requested by offset and then by label — why can the two return different row counts?

level: juniorimportance: must knowfreq 66%

basics

~20 s

A range of offsets in a zero-based host is half-open — the endpoint is excluded — so it returns three rows. A range of labels includes both ends, so it returns four. Same-looking request, different rule.

open as a page

An ordering step is given region ascending and amount descending — what does each key govern in the result?

level: juniorimportance: must knowfreq 74%

basics

~20 s

Region sets the overall order and groups the rows into blocks; amount only arranges rows inside a block where the region is equal. Each key carries its own direction, so mixing ascending and descending in one step is normal.

open as a page

Two full-length condition columns over the same 10,000 rows must both hold. Why does the host's scalar connective fail, and what combines them instead?

level: juniorimportance: must knowfreq 72%

basics

~20 s

Two condition columns combine position by position into a third full-length column, one outcome per row. The host's scalar connective wants a single truth value from each side, and a whole column has none, so it either refuses or quietly answers a different question.

open as a page

When a 1,000-row table is restricted to rows whose amount exceeds a threshold, what intermediate object is built, and how long is it?

level: juniorimportance: must knowfreq 72%

basics

~20 s

A condition column is built first: one true-or-false outcome per row, so 1,000 entries long, exactly as long as the table. That full-length column then addresses the table, and the rows whose outcome was true come back whole.

open as a page

A subset of rows is bound to a new name, then a column on that name is set to zero — what does the write target?

level: juniorimportance: must knowfreq 62%

basics

~10 s

The write targets whatever the first statement produced — the original table is not named in the second statement at all. Whether the original changes depends entirely on what that intermediate object was.

open as a page

An ordering step returns rows with equal keys in a different order on a bigger input — why, and what fixes it?

level: middleimportance: must knowfreq 62%

basics

~20 s

Nothing constrained those rows. An ordering step orders rows whose keys differ; rows that tie keep the order they arrived in only where the design promises it, and where it does not, their arrangement can shift with size, version or parallelism. Add a tie-breaking key.

open as a page

A condition column over 1,000 rows holds 412 true, 500 false and 88 outcomes that are neither — how many rows come back?

level: middleimportance: must knowfreq 63%

basics

~20 s

412, 500, or an error — the design decides. Most treat an outcome that is neither true nor false as not-true and return 412; some refuse the operation; some emit a placeholder row for each, returning 500 of which 88 hold no values.

open as a page

Which row selections can be handed back as a window on the original's storage, and which must allocate?

level: middleimportance: must knowfreq 72%

basics

~20 s

Only a selection describable as a start, a count and a step can be expressed as a window, because those three numbers are the whole description. Positions with no regular pattern, and selections driven by a condition column, must gather their values into fresh storage.

open as a page

Why can a write expressed as one combined address not be lost, when the same write split in two can be?

level: middleimportance: must knowfreq 70%

basics

~20 s

One combined address hands the whole target, rows and column together, to the original table, which performs the write itself. Split in two, the second step stores into an intermediate the first step produced, and that intermediate may be discarded.

open as a page

What distinguishes a selection that is a window onto the original's bytes from one holding storage of its own?

level: juniorimportance: should knowfreq 58%

basics

~20 s

A window reads the original's storage: no bytes were allocated for the values, and the original cannot be released while the window lives. Storage of its own holds freshly allocated bytes and is independent of the source.

open as a page

A lookup of one row label returns twelve rows — what does that tell you, and what would the same request by offset return?

level: middleimportance: should knowfreq 49%

basics

~20 s

It tells you the row labels are not unique, so they are not a key. Label addressing matches and returns every row carrying that label. An offset cannot do this: one offset names exactly one row, whatever the data looks like.

open as a page

A table with integer row labels is subscripted with 3 — what decides whether that names a label or an offset?

level: middleimportance: should knowfreq 58%

basics

~20 s

The design does. Where two separately named addressing surfaces exist, the surface you called decides and nothing is guessed. Where a single subscript is overloaded, an integer resolves as a label once the row labels are integers, and as an offset otherwise.

open as a page

An ordering key is absent on a quarter of the rows — where do those rows land in the result?

level: middleimportance: should knowfreq 54%

basics

~20 s

Wherever the design puts them, which is not something to assume. Some place them last, some first, some expose an option that says which end, and some leave it to the comparison. State the placement you want, or arrange it with a derived key.

open as a page

In a host that repurposes its bitwise operators for element-wise logic, why must each comparison in a combined condition be parenthesised?

level: middleimportance: should knowfreq 56%

basics

~20 s

Borrowed bitwise operators keep a precedence designed for bit arithmetic, which binds tighter than comparison. Unparenthesised, the connective grabs the two middle operands instead of the two comparison outcomes, so the wrong pair is compared and any error names types rather than precedence.

open as a page

A combined condition keeps 6,120 rows and its complement keeps 3,720, out of 10,000. Where did the other 160 rows go?

level: middleimportance: should knowfreq 44%

basics

~20 s

Some rows had a third outcome, neither true nor false, in one of the two conditions, and the combination carried it through. A restriction that keeps only definitely-true rows drops them from the condition and from its complement alike, so the two counts do not sum.

open as a page

Why does restricting 50 million rows down to 3 still cost a full pass and a table-length intermediate?

level: middleimportance: should knowfreq 55%

basics

~20 s

Because selection by condition is not a search. An outcome is computed for every one of the 50 million rows and held as a condition column of that length; only then are the 3 true positions addressed. Rarity makes the result small, not the work.

open as a page

Why might values written into selected rows from another labelled column not land in the order they were written?

level: middleimportance: should knowfreq 45%

basics

~20 s

The right-hand side may be reconciled with the target by row label rather than laid down in order. Labels that do not overlap then produce absent cells rather than an error, and labels in a different order put values on different rows.

open as a page

After rows are removed, a saved offset still resolves while a saved row label no longer does — why, and which failure is safer?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Removing rows renumbers positions contiguously while leaving the survivors' labels alone, so an offset resolves against the new layout and names a different record. The label failure is safer: it cannot hand back a plausible wrong row.

open as a page

A report asks for the ten largest rows and then prints them as ranked — what assumption can fail?

level: seniorimportance: should knowfreq 44%

basics

~20 s

That asking for the ten largest also put them in order. A top-n pass answers membership, not arrangement: some designs hand the n rows back unordered, and which of several tied rows takes the last place is unspecified unless a tie-break is given.

open as a page

A ratio test is combined with a guard meant to exclude rows whose denominator is zero, yet those rows still produced warnings. Why?

level: seniorimportance: should knowfreq 47%

basics

~20 s

Both conditions are whole columns, computed in full before they meet, so the element-wise combiner evaluates both sides on every row. The guard never prevented anything: the division already ran on exactly the rows it was meant to exclude.

open as a page

A condition column built from a re-ordered copy of a table is then used to restrict the original — what comes back?

level: seniorimportance: should knowfreq 47%

basics

~20 s

It depends on the matching rule. Aligned by row label, each outcome lands on the row it was computed for and the right rows come back. Matched by position, the outcomes land on whatever rows now sit there — silently wrong.

open as a page

A job keeps ten rows out of each million-row table it reads, yet memory never falls - what should you suspect about the kept results?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Suspect the kept results are windows onto the originals' bytes. A window holds a reference to the whole buffer, so ten visible rows keep a million resident, and nothing is released until the kept rows are materialised into storage of their own.

open as a page

Two writes update the same column of a table in sequence, and the second one's condition was computed before the first ran — what goes wrong, and what changes if it is recomputed?

level: seniorimportance: should knowfreq 38%

basics

~20 s

A condition captured before a write is blind to the rows that write changed, so the second write addresses the old population. Recomputed, it does the opposite: it can cascade over rows the first write just created.

open as a page

The same selection expression shares storage in one tool and allocates in another - what should portable code commit to instead?

level: seniorimportance: nice to knowfreq 34%

basics

~20 s

Commit to the requirement, not to the observed behaviour. Whether a result shares bytes is a design decision that the text of an expression cannot express, so state whether the source must be releasable and materialise when it must be, instead of inheriting whatever the tool did.

open as a page

Your codebase updates tables by writing into selected rows — what standing rule would you set so a lost or misplaced write cannot reach production, and what does it cost?

level: principalimportance: nice to knowfreq 24%

basics

~20 s

Scope the rule by blast radius rather than applying one everywhere: reject split-address writes in review across the codebase, and require a value read-back only where the written table is consumed by a later step. Each control has a different price.

open as a page