PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question tests practical data structure design and object-oriented system modeling, requiring the implementation of a hierarchical moderator management system backed by time-ordered logs. It evaluates proficiency with ordered collections, hash maps, and linked list manipulation to support rank queries, permission checks, and rank mutations across multi-community scopes.

  • medium
  • Reddit
  • Coding & Algorithms
  • Software Engineer

Moderator System with Ranking, Communities, and Demotion

Company: Reddit

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

You are designing a system that tracks moderator privileges for an online community using a time-ordered log of moderation actions. Each log record captures when a user gains or loses moderator status. The system must support permission checks for removing moderators and must also return the current moderator list in the correct hierarchy. In this system, moderators are ranked by **when they most recently became a moderator**. Among all currently active moderators, a user who became a moderator *earlier* has a **higher** level than a user who became a moderator *later*. If a user loses and later regains moderator status, the timestamp of the most recent "added" action is what counts toward the ranking. This problem is built up in three parts. Implement the `ModSystem` class incrementally; later parts extend the earlier ones. --- ### Part 1 — Single-community moderator system Implement the `ModSystem` class: - `ModSystem(List<String> logs)` — Initializes the moderator system from the given chronological list of log entries. Each entry is a string in the format `"<targetUser>,<action>,<actorUser>,<timestamp>"`, where: - `targetUser` is the user whose moderator status is affected. - `action` is either `"added"` or `"removed"`, indicating whether the user is granted or revoked moderator status. - `actorUser` is the user who performed the action. - `timestamp` is a string representing a non-negative integer. The log entries are given in strictly increasing order of `timestamp`. - `boolean canRemoveMod(String targetUser, String actorUser)` — Returns `true` **only if all** of the following conditions hold; otherwise returns `false`: 1. Both `targetUser` and `actorUser` are currently moderators. 2. `actorUser` is not the same user as `targetUser`. 3. `actorUser` has a **higher** moderator level than `targetUser` according to the ranking rules above (i.e. `actorUser` most recently became a moderator at an *earlier* timestamp than `targetUser`). - `List<String> getModRanking()` — Returns the current list of moderators ordered from **highest** level to **lowest** level (earliest-most-recent-promotion first). ### Part 2 — Multiple communities Extend the system so that moderator status is scoped per **community**. The log format gains a leading community field, and every query is scoped to a single community. A user may be a moderator in several communities independently; rankings are computed **within** a community only. - `ModSystem(List<String> logs)` — Each log entry is now `"<community>,<targetUser>,<action>,<actorUser>,<timestamp>"`. Timestamps are globally increasing across all communities. - `boolean canRemoveMod(String community, String targetUser, String actorUser)` — Same rules as Part 1, but restricted to moderators of the given `community`. - `List<String> getModRanking(String community)` — Returns the moderator ranking (highest to lowest) for the given `community`. Returns an empty list if the community has no moderators. ### Part 3 — Demotion Extend the Part 2 system to support manually demoting a moderator within a community. - `void demote(String community, String user)` — Decreases `user`'s moderator rank by **exactly one position** in the current ordering of that community. For example, if the current ranking from highest to lowest in a community is `user1 -> user2 -> user3`, then `demote(community, "user1")` produces `user2 -> user1 -> user3`. A subsequent `demote(community, "user1")` would produce `user2 -> user3 -> user1`. The operation has **no effect** if `user` is already the lowest-ranked moderator in that community, or if `user` is not currently a moderator in that community. After a demotion, `getModRanking(community)` and `canRemoveMod(community, ...)` must reflect the new ordering (i.e. ranking is determined by the maintained order, which a demotion mutates, not purely by promotion timestamp). --- ### Constraints - `1 <= logs.length <= 10^5`. - All user names, community names, and actions consist of non-empty lowercase/uppercase alphanumeric characters; field values themselves contain no commas. - Timestamps are distinct non-negative integers given in strictly increasing order. - A `"removed"` action is only logged for a user who is currently a moderator; an `"added"` action is only logged for a user who is not currently a moderator (in that community). - `canRemoveMod`, `getModRanking`, and `demote` may each be called up to `10^5` times in total. - For Part 1 / Part 2, ranking ties cannot occur because all promotion timestamps are distinct. ### Examples **Part 1** ``` logs = [ "alice,added,system,1", "bob,added,alice,2", "carol,added,alice,3", "bob,removed,alice,4", "bob,added,carol,5" ] getModRanking() -> ["alice", "carol", "bob"] canRemoveMod("bob", "alice") -> true // alice (ts 1) outranks bob (ts 5) canRemoveMod("carol", "bob") -> false // bob (ts 5) is lower than carol (ts 3) canRemoveMod("alice", "alice") -> false // same user canRemoveMod("dave", "alice") -> false // dave is not a moderator ``` **Part 3** ``` // within community "c1", current ranking is ["user1", "user2", "user3"] demote("c1", "user1") // ranking -> ["user2", "user1", "user3"] getModRanking("c1") -> ["user2", "user1", "user3"] demote("c1", "user3") // user3 already lowest -> no effect getModRanking("c1") -> ["user2", "user1", "user3"] ```

Quick Answer: This question tests practical data structure design and object-oriented system modeling, requiring the implementation of a hierarchical moderator management system backed by time-ordered logs. It evaluates proficiency with ordered collections, hash maps, and linked list manipulation to support rank queries, permission checks, and rank mutations across multi-community scopes.

Moderator System I — Single Community Ranking

Implement a single-community moderator system driven by a chronological log of `"<targetUser>,<action>,<actorUser>,<timestamp>"` records (`action` is `added` or `removed`). Moderators are ranked by *when they most recently became a moderator*: an earlier most-recent promotion means a higher level. Here the class is simulated as a function `solution(logs, queries)`. `logs` initializes the system. `queries` is a list of operations, each a list whose first element names the method: - `["getModRanking"]` -> list of moderators, highest level to lowest. - `["canRemoveMod", targetUser, actorUser]` -> `True` iff both are current mods, they differ, and `actorUser` outranks `targetUser` (promoted earlier). Return the list of results, one per query.

Constraints

  • 1 <= logs.length <= 10^5
  • Field values contain no commas; names/actions are non-empty alphanumeric.
  • Timestamps are distinct non-negative integers in strictly increasing order.
  • A 'removed' is only logged for a current mod; an 'added' only for a non-mod.
  • Up to 10^5 total query calls.

Examples

Input: (["alice,added,system,1", "bob,added,alice,2", "carol,added,alice,3", "bob,removed,alice,4", "bob,added,carol,5"], [["getModRanking"], ["canRemoveMod", "bob", "alice"], ["canRemoveMod", "carol", "bob"], ["canRemoveMod", "alice", "alice"], ["canRemoveMod", "dave", "alice"]])

Expected Output: [["alice", "carol", "bob"], True, False, False, False]

Explanation: alice(ts1) > carol(ts3) > bob(ts5 after re-add). alice outranks bob -> True; bob is below carol -> False; same user and non-mod -> False.

Input: ([], [["getModRanking"]])

Expected Output: [[]]

Explanation: Empty log: no moderators, ranking is empty.

Input: (["u1,added,sys,10"], [["getModRanking"], ["canRemoveMod", "u1", "u1"]])

Expected Output: [["u1"], False]

Explanation: Single mod; a user can never remove themselves.

Input: (["a,added,s,1", "b,added,s,2", "a,removed,b,3", "a,added,b,4"], [["getModRanking"], ["canRemoveMod", "a", "b"], ["canRemoveMod", "b", "a"]])

Expected Output: [["b", "a"], True, False]

Explanation: After re-adding a at ts4, a's most-recent promotion (4) is later than b's (2), so b outranks a.

Hints

  1. Track each user's most-recent promotion timestamp and whether they are currently a mod; clear both on 'removed'.
  2. Ranking = users sorted ascending by most-recent promotion timestamp (earlier promotion = higher level).
  3. canRemoveMod needs both to be current mods, different from each other, and actor's promotion timestamp strictly earlier than target's.

Moderator System II — Multiple Communities

Extend Part 1 so moderator status is scoped per **community**. Each log record is now `"<community>,<targetUser>,<action>,<actorUser>,<timestamp>"` and every query names a community. Rankings are computed within a single community only; a user may moderate several communities independently. `solution(logs, queries)` queries: - `["getModRanking", community]` -> ranking for that community (empty list if none). - `["canRemoveMod", community, targetUser, actorUser]` -> same rule as Part 1, restricted to that community. Return the list of results, one per query.

Constraints

  • 1 <= logs.length <= 10^5
  • Field values contain no commas; names/actions are non-empty alphanumeric.
  • Timestamps are distinct non-negative integers in strictly increasing order.
  • A 'removed' is only logged for a current mod; an 'added' only for a non-mod.
  • Up to 10^5 total query calls.

Examples

Input: (["c1,alice,added,system,1", "c1,bob,added,alice,2", "c2,bob,added,system,3", "c1,carol,added,alice,4", "c1,bob,removed,alice,5", "c1,bob,added,carol,6"], [["getModRanking", "c1"], ["getModRanking", "c2"], ["canRemoveMod", "c1", "bob", "alice"], ["canRemoveMod", "c1", "carol", "bob"], ["canRemoveMod", "c2", "bob", "alice"]])

Expected Output: [["alice", "carol", "bob"], ["bob"], True, False, False]

Explanation: Rankings are per community. bob is a mod of c2 but alice is not, so canRemoveMod in c2 is False.

Input: ([], [["getModRanking", "nope"]])

Expected Output: [[]]

Explanation: Unknown community returns an empty ranking.

Input: (["x,u1,added,s,10", "x,u2,added,s,20"], [["canRemoveMod", "x", "u1", "u1"], ["canRemoveMod", "x", "u2", "u1"], ["canRemoveMod", "y", "u2", "u1"]])

Expected Output: [False, True, False]

Explanation: u1(ts10) outranks u2(ts20) in x; community y has no mods so the query is False.

Input: (["a,m,added,s,1", "a,m,removed,s,2"], [["getModRanking", "a"], ["canRemoveMod", "a", "m", "s"]])

Expected Output: [[], False]

Explanation: m was added then removed -> community a has no current mods.

Hints

  1. Key everything by community: keep a separate {user: timestamp} map per community.
  2. Scope each query to its community map; an unknown community yields an empty ranking and False checks.
  3. Independence: the same user can be a mod in several communities with different timestamps.

Moderator System III — Demotion

Extend Part 2 with manual demotion. After demotions, the ranking is driven by a **maintained order** (seeded from promotion timestamps), not purely by timestamp. `solution(logs, queries)` queries: - `["getModRanking", community]` -> current order, highest to lowest. - `["canRemoveMod", community, targetUser, actorUser]` -> uses the maintained order (a smaller position means a higher level). - `["demote", community, user]` -> moves `user` down exactly one position. No effect if `user` is already lowest or is not a current mod of that community. Demotes append `None` to the results list. For example, with order `user1 -> user2 -> user3`, `demote(c, "user1")` yields `user2 -> user1 -> user3`; demoting again yields `user2 -> user3 -> user1`.

Constraints

  • 1 <= logs.length <= 10^5
  • Field values contain no commas; names/actions are non-empty alphanumeric.
  • Timestamps are distinct non-negative integers in strictly increasing order.
  • A 'removed' is only logged for a current mod; an 'added' only for a non-mod.
  • Up to 10^5 total query calls.

Examples

Input: (["c1,user1,added,s,1", "c1,user2,added,s,2", "c1,user3,added,s,3"], [["getModRanking", "c1"], ["demote", "c1", "user1"], ["getModRanking", "c1"], ["demote", "c1", "user1"], ["getModRanking", "c1"]])

Expected Output: [["user1", "user2", "user3"], None, ["user2", "user1", "user3"], None, ["user2", "user3", "user1"]]

Explanation: Each demote moves user1 down one slot in the maintained order.

Input: (["c1,user1,added,s,1", "c1,user2,added,s,2", "c1,user3,added,s,3"], [["demote", "c1", "user1"], ["demote", "c1", "user3"], ["getModRanking", "c1"], ["demote", "c1", "ghost"], ["getModRanking", "c1"]])

Expected Output: [None, None, ["user2", "user1", "user3"], None, ["user2", "user1", "user3"]]

Explanation: Demoting the lowest-ranked user3 or a non-mod ghost has no effect.

Input: (["c1,a,added,s,1", "c1,b,added,s,2", "c1,c,added,s,3"], [["demote", "c1", "a"], ["canRemoveMod", "c1", "a", "b"], ["canRemoveMod", "c1", "b", "a"], ["canRemoveMod", "c1", "c", "a"]])

Expected Output: [None, True, False, True]

Explanation: After demoting a, order is b > a > c. b outranks a (True); a no longer outranks b (False); a still outranks c (True).

Input: ([], [["getModRanking", "x"], ["demote", "x", "u"], ["getModRanking", "x"]])

Expected Output: [[], None, []]

Explanation: Demoting in an empty community is a no-op.

Input: (["c1,solo,added,s,1"], [["demote", "c1", "solo"], ["getModRanking", "c1"]])

Expected Output: [None, ["solo"]]

Explanation: The only (and therefore lowest-ranked) mod cannot be demoted.

Hints

  1. Seed each community's order from promotion timestamps once, then maintain that explicit ordered list.
  2. demote swaps the user with the next-lower neighbor; skip if the user is last or absent.
  3. After demotions, derive level from list position (lower index = higher level), not from timestamps.
Last updated: Jun 24, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement a simplified memcached server - Reddit (medium)
  • Solve palindrome and list tasks - Reddit (hard)
  • Merge Message Context Windows - Reddit (medium)
  • Implement a sliding-window rate limiter - Reddit (medium)
  • Find word sequence with 1–2 char changes - Reddit (Medium)