Middle · Trace · Mutation review

Trace the complete program for debug mutation by choosing ownership. State the exact stdout, then justify the state transitions and relevant edge conditions.

Think through your answer before opening the explanation.

Coding interviews

using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

var source=new List<int>{1,2,3,4};
int[] filtered=source.Where(x=>x%2!=0).ToArray();
Console.WriteLine("copy:"+string.Join(",",filtered)); Console.WriteLine("source:"+string.Join(",",source));
var owned=new List<int>(source); int removed=owned.RemoveAll(x=>x%2==0);
Console.WriteLine("in place:"+string.Join(",",owned)+";removed:"+removed);
Reveal answer and reasoning

The output lines, in order, are “copy:1,3”; “source:1,2,3,4”; “in place:1,3;removed:2”. Filtering odd values into an array produces one and three while leaving the original list one,two,three,four. A separate owned copy then calls RemoveAll and reports two removed entries. Both final selections agree, but their aliasing behavior differs. The harness keeps both lists available so the difference remains observable. ToArray forces the filtered query before the original list is displayed, fixing that result to the observed values.

RemoveAll evaluates the predicate over its owned list and returns the removal count. The final list and the count provide two independent aspects of the postcondition: what remains and how much was removed.

Filtering and RemoveAll each take O(n) predicate work. The filtered array requires O(r) result storage, while RemoveAll compacts the owned list in place with constant auxiliary state. Constructing the separate demonstration copy itself costs O(n) storage; do not omit that cost when describing this exact program. A deferred Where query is not yet a snapshot, so source mutation before enumeration changes its result.

Removing by increasing index can skip shifted elements. Concurrent mutation adds another ownership problem that neither a filtered query nor an unsynchronized list solves automatically.

What a strong answer covers

  • Exact output: copy:1,3 | source:1,2,3,4 | in place:1,3;removed:2
  • Filtering odd values into an array produces one and three while leaving the original list one,two,three,four.
  • A deferred Where query is not yet a snapshot, so source mutation before enumeration changes its result.

Common pitfall

A deferred Where query is not yet a snapshot, so source mutation before enumeration changes its result. Removing by increasing index can skip shifted elements. Concurrent mutation adds another ownership problem that neither a filtered query nor an unsynchronized list solves automatically.

Follow-up questions

  1. Test all-matching, none-matching and alternating lists. Hint: count the removed items separately from the kept items and verify the original list remains unchanged only for the copy-returning path.
  2. Does returning IReadOnlyList alone guarantee that the underlying list cannot change?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions