FreeExam

Coding

Write the code an ML engineer writes around a model, such as cleaning and splitting data, tokenizing and batching, evaluation and error analysis, and serving, in Python in the editor.

These problems are original practice. They are not questions from a named employer or a live hiring loop.

  1. 1.Remove near-duplicate texts

    Training data often repeats a text with different case or spacing. Write dedupe_texts(texts) that keeps the first occurrence of each text, comparing texts after lowercasing, trimming the ends, and collapsing every run of whitespace to one space. Return the kept texts unchanged, in their original order.

  2. 2.Load a JSON Lines dataset

    Write load_jsonl(lines, required) to read a dataset with one JSON object per line. Keep an object when every field in required is present and not None. Skip empty or whitespace-only lines. Count every other dropped line: invalid JSON, not an object, or missing a required field. Return [records, bad]: the kept objects in order, and that count.

  3. 3.Fill missing values with the median

    Write impute_median(values) for a numeric feature where missing entries are None. Replace each None with the median of the present values, averaging the two middle values for an even count. If every value is missing, use 0.0.

  4. 4.Encode categories

    Write encode_categories(train, test) for a categorical feature. Give each distinct train value an id in order of first appearance, starting at 0. Map test values with the same ids, and give any value not seen in train the id equal to the number of train categories. Return [train_ids, test_ids].

  5. 5.K-fold splits

    Write k_fold_splits(n, k) for cross-validation without shuffling. Split indexes 0 to n − 1 into k contiguous validation folds, in order; when n does not divide evenly, the first n % k folds get one extra index. For each fold return [train, validation], where train is every other index in ascending order.

  6. 6.Group k-fold by user

    Rows from one user must not land in both train and validation. Write group_k_fold(groups, k), where groups[i] is the user of row i. Give each distinct user a fold in order of first appearance: the first user to fold 0, the second to fold 1, and so on, wrapping after fold k − 1. Return k lists of row indexes, one per fold, each in ascending order. A fold with no users is an empty list.

  7. 7.Build a vocabulary

    Write build_vocab(texts, min_count, specials) for a word-level tokenizer. Lowercase each text and split on whitespace. Give the special tokens ids 0, 1, 2, … in order. Then add the words seen at least min_count times, most frequent first with ties alphabetical, skipping any word that is already a special token. Return a dict of token to id.

  8. 8.Train byte-pair encoding

    Write bpe_merges(word_counts, num_merges) for byte-pair encoding. Words start as single characters. Each round, count adjacent symbol pairs weighted by word count, and merge the most frequent pair everywhere, left to right in a word: merging "a a" turns "aaa" into ["aa", "a"]. Ties go to the smaller left, then right, symbol. Return merges as "left right" strings; stop when no pairs remain.

  9. 9.Pad a batch

    Write pad_batch(sequences, pad_id) to batch token ids for a model. Right-pad every sequence to the longest length with pad_id, and build an attention mask with 1 for real tokens and 0 for padding. Return {"input_ids": ..., "attention_mask": ...}.

  10. 10.Batch by length

    To cut padding, batch examples of similar length. Write length_buckets(lengths, batch_size): sort example indexes by length, shortest first, keeping the original order for equal lengths, then cut that order into batches of batch_size. The last batch may be smaller. Return the batches of indexes.

  11. 11.Chunk tokens with overlap

    Write chunk_tokens(tokens, size, overlap) to split a document for retrieval. The first chunk starts at index 0, and each next chunk starts size − overlap tokens after the previous one. A chunk holds up to size tokens. Stop after the first chunk that contains the last token. An empty list gives no chunks. 0 ≤ overlap < size.

  12. 12.Align labels to subword tokens

    A subword tokenizer splits words into pieces. word_ids gives, for each token, the index of its word, or None for a special token. Write align_labels(word_ids, word_labels) that gives the first piece of each word that word's label and every other token -100, the value the loss ignores.

  13. 13.Early stopping

    Write early_stop(val_losses, patience, min_delta). Epoch 0 sets the best loss. A later epoch improves, and becomes the new best, when its loss is below the best minus min_delta. Stop at the first epoch that is patience epochs after the last improvement. Return a dict with best_epoch, the last improving epoch, and stop_epoch, or the last index if training never stops early.

  14. 14.Parse training logs

    Training logs print lines like "step=10 loss=0.52 acc=0.81". Write parse_metrics(lines) that returns a dict from each metric name to a list of [step, value] pairs in log order. Skip a line without a numeric step field. Within a line, skip any field that is not name=number. step itself is not a metric; use it as an integer, and every metric value as a float.

  15. 15.One k-means step

    Write kmeans_step(points, centroids) for one round of k-means. Assign each point to its nearest centroid by Euclidean distance, ties going to the lower index, then move each centroid to the mean of its points. A centroid with no points stays where it is. Return the new centroids in their original order.

  16. 16.K-nearest neighbors

    Write knn_classify(points, labels, query, k). Take the k training points nearest to query by Euclidean distance, distance ties going to the lower index, and return the most common label among them. If labels tie on votes, return the tied label whose point comes first in that nearest-first order.

  17. 17.Confusion matrix

    Write confusion_matrix(y_true, y_pred, num_classes). Row i counts examples whose true class is i, and column j counts those predicted as j.

  18. 18.Precision, recall, and F1

    A fraud model flags transactions. Write precision_recall_f1(y_true, y_pred) for labels of 0 and 1, where 1 is fraud. Return a dict with keys "precision", "recall", and "f1". When a ratio has a zero denominator, use 0.0.

  19. 19.Most common confusions

    For error analysis, write top_confusions(y_true, y_pred, n) that counts mistakes as (true, predicted) pairs, ignoring correct predictions. Return the n most common as [true, predicted, count], most frequent first, ties broken by true label and then predicted label, ascending.

  20. 20.Accuracy by slice

    Write slice_accuracy(rows) to check a model per segment. Each row is {"slice": name, "label": y, "pred": p}. Return a dict from slice name to [correct, total], plus an "all" entry for every row together. Treat a row whose pred is None as wrong.

  21. 21.ROC AUC

    Write roc_auc(labels, scores): the chance that a random positive gets a higher score than a random negative, with ties counting half. Labels are 0 or 1. Return None when only one class is present.

  22. 22.Mean reciprocal rank

    Write mean_reciprocal_rank(queries). Each query is {"ranked": [ids], "relevant": [ids]}. Score a query as 1 / the position of its first relevant id, counting from 1, or 0 when none appears. Return the mean, or 0.0 when there are no queries.

  23. 23.Word error rate

    Write word_error_rate(reference, hypothesis) for a speech model. Split both on whitespace and return the word-level edit distance (substitutions, insertions, and deletions) divided by the number of reference words. The reference is never empty.

  24. 24.Entity spans from BIO tags

    A named-entity model tags tokens as B-TYPE, I-TYPE, or O. Write bio_spans(tags) that returns entity spans as [type, start, end], end exclusive. An I- tag continues the open span only when the type matches; otherwise it starts a new span. B- always starts a new span, and O closes any open span.

  25. 25.Intersection over union

    Boxes are [x1, y1, x2, y2] with x1 < x2 and y1 < y2. Write iou(a, b), the intersection area divided by the union area. Boxes that only touch or do not overlap score 0.0.

  26. 26.Non-maximum suppression

    Write nms(boxes, scores, threshold) for an object detector. Visit boxes from highest score to lowest, ties going to the lower index. Keep a box unless its IoU with an already kept box is greater than threshold. Return the kept indexes in the order they were kept. Boxes are [x1, y1, x2, y2].

  27. 27.Top-p token set

    Write top_p_tokens(probs, p) for nucleus sampling. Sort token indexes by probability, highest first, ties going to the lower index, and keep the shortest prefix whose total probability reaches at least p. Return the kept indexes in that order.

  28. 28.Beam search

    Write beam_search(start, log_probs, steps, width). log_probs[token] maps each next token to its log probability. Start from [start] with total 0. In each of the steps rounds, extend every kept sequence by each next token of its last token, add the log probabilities, and keep the width highest totals, ties going to the alphabetically smaller list. Return the best final sequence.

  29. 29.LRU cache

    An embedding service caches results for recent inputs. Write cache_hits(requests, capacity) that simulates a least-recently-used cache of up to capacity keys. For each request return "hit" if the key is cached; otherwise return "miss" and add it, evicting the least recently used key when full. A hit makes the key the most recent. With capacity 0, nothing is ever cached.

  30. 30.Sliding-window rate limiter

    Write allow_requests(times, limit, window) for a model API. times are request times in seconds, sorted, and several requests can share a time. Allow the request at time t when fewer than limit earlier allowed requests happened after t − window. Rejected requests do not count toward the limit. Return True or False for each request.

  31. 31.Dynamic batching

    An inference server groups queued requests. Write dynamic_batches(token_counts, max_batch, max_tokens). Walk requests in order and add each to the current batch unless that would exceed max_batch requests or max_tokens total tokens; then start a new batch. A request over max_tokens goes in a batch by itself. Return batches of indexes.

  32. 32.Pipeline run order

    A training pipeline has steps with dependencies. Write run_order(deps), where deps maps every step to the list of steps it needs first. Return an order that runs each step after its dependencies, picking the alphabetically smallest ready step each time. Return None if the dependencies form a cycle.