Application settings such as timeouts, hosts, and feature switches are read all over a codebase. Every component must see the same values, and a change made in one place must be visible everywhere else.
AppConfig starts as an ordinary class. Its constructor is public and getInstance() builds a new object on every call, so a value stored through one handle is missing through the next. Your task is to turn AppConfig into a thread-safe singleton and complete its methods.
ConfigGate is the driver used by the judge. It asks AppConfig for two handles independently and delegates A-labelled and B-labelled calls through those handles. It is already complete and must not be modified.
AppConfig.getInstance() returns one controlled, thread-safe instance. Code outside the class must not be able to construct a second one.boolean set(String key, String value) stores the value. It returns true when the key is new and false when it replaced an existing value.String get(String key) returns the stored value, or "MISSING" when the key is absent.int size() returns the number of stored keys.void reset() removes every key. It changes only the stored data; the singleton object stays the same.ConfigGate() calls reset() for test isolation, then obtains handle A and handle B with two separate getInstance() calls.boolean sameInstance() returns whether the two handles refer to the same AppConfig object.setA and getA use handle A; setB and getB use handle B.int size() on the gate reads through handle A.All judge cases run in one process. reset() clears the settings between cases, but it must never clear or replace the stored singleton reference.
Thread-safety requirement: The singleton must be thread-safe: both instance publication and every read or write of the settings map must remain correct under concurrent calls.
TypeScript operations are synchronous within one JavaScript realm; separate workers have separate singleton scopes.
Input:
Output:
Explanation: Handle A and handle B were obtained independently but refer to the same object. A value stored through A is therefore readable through B.
Input:
Output:
Explanation: The first write creates the key. The second write through the other handle replaces the value in place, so set returns false and the map still holds one key.
1 <= key.length <= 30 and 1 <= value.length <= 30100 calls in total are made across all methods.reset() must clear the settings without replacing the singleton object.Turn AppConfig into a thread-safe singleton and complete its TODOs. ConfigGate is complete driver code and must not be modified.
Full marks when `AppConfig` owns one safely published instance for the lifetime of the process and construction is controlled. Lose points heavily when construction remains public, the accessor can return different objects, or initialization uses an unsafe check-then-create sequence.
Full marks when `set`, `get`, `size`, and `reset` protect the same map so the new-key check and the write cannot interleave and both driver handles observe one set of values. Lose points for unsynchronized mutation or settings stored outside `AppConfig`.
Full marks when `set` reports `true` only for a new key, overwrites replace the value in place, and absent keys read as `MISSING`. Lose points for storing duplicate entries, recreating the singleton between cases, or printing to stdout.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new ConfigGate() | null |
| sameInstance() | true |
| setA("timeout", "30") | true |
| getB("timeout") | "30" |
Handle A and handle B were obtained independently but refer to the same object. A value stored through A is therefore readable through B.
Run checks these cases. Submit also runs a larger hidden set.

