How does WebSocket connection work in architecture — when is it established and who communicates with whom?
Golang
How to move the window in the sliding window algorithm?
Tell about the most complex and interesting problem you have solved, especially about architectural experience.
Are you currently living in Moscow? Which city are you considering? Do you consider a hybrid work format? What stage are you at in your job search?
Could you state your current income level?
Do you have other active interview processes?
How are these metrics integrated and displayed in Grafana?
What was the team composition you worked with last time?
Designing a scalable messaging system supporting 150 million users, 75 million DAU, 225 million MAU, 1.2M read / 300k write QPS, 5 million concurrent users, 60 PB of new data annually, 30% growth per year, P99 <200 ms for read, <300 ms for write, SLA 99.95%. CONTEXT You need to design a distributed messaging system similar to WhatsApp, supporting both 1:1 and group chats, ensuring message delivery, displaying user online statuses, and transmitting multimedia files (photos, videos, audio). The system must ensure high availability and low latency, handle high concurrency, and scale globally. FUNCTIONAL REQUIREMENTS - Support for personal (1:1) and group chats with the ability to add/remove participants - Sending and receiving text messages and multimedia files NON-FUNCTIONAL REQUIREMENTS: - No explicit implementation of end-to-end encryption at the service or client level, except for a general annotation. - No explicit description of sharding and database replication by chat_id or user_id for scalability and fault tolerance. - No explicit component or mechanism for offline message synchronization and delivery receipts. - It is not clear how load balancing is implemented between databases and services, especially during peak loads. **Bottlenecks to pay attention to:** (The architecture diagram shows Load Balancer, API Gateway, Message Queue, Service, Cache, Database, Object Storage, and CDN)
What methods can be used to improve the efficiency of searching for elements in a Map data structure?
Do you have an active GitHub or LinkedIn?
What is the problem with the current implementation of map update in the worker (tasksRes[t.id][task{...}])?
Briefly tell what you did at previous jobs, what features you implemented?
Design a scalable messenger supporting 150 million users, 75 million DAU, 225 million MAU, 1.2M read / 300k write peak QPS, 5 million concurrent users, 60 PB new data per year, 30% growth annually, SLA 99.95%, p99 <200 ms for read, <300 ms for write. CONTEXT Design a distributed messaging system similar to WhatsApp supporting 1:1 and group chats, message delivery, online status display, and multimedia transfer (photos, videos, audio). The system must ensure high availability, low latency, high concurrency, and global scalability. FUNCTIONAL REQUIREMENTS - Support for personal (1:1) and group chats with add/remove participants - Sending and receiving text and multimedia files No explicit implementation of end-to-end encryption at service or client level, apart from general annotation. - No clear description of sharding and replication of databases by chat_id or user_id for scalability and fault tolerance. - No explicit component or mechanism for offline message synchronization and delivery receipts. - How load balancing between databases and services is implemented, especially during peak loads. **Bottlenecks to consider:**
/ * There are two PostgreSQL servers: * PROD - OLTP server, * STATS - server for long analytical queries. Currently, the production database has a large (10Tb) table: CREATE TABLE profiles( id SERIAL, data JSONB ) The table may have "holes", i.e., some `id`s may be skipped. You need to write a program to copy the profiles table from PROD to STATS. The following interfaces are assumed for database interaction: type Row []interface{} type Database interface { // the implementation of the Database interface can re-establish connections // the call to SaveRows is idempotent io.Closer GetMaxID(ctx context.Context) (uint64, error) LoadRows(ctx context.Context, minID, maxID uint64) ([]Row, error) // [minID, maxID] SaveRows(ctx context.Context, rows []Row) error } func Connect(ctx context.Context, dbname string) (Database, error) // CopyTable // If full=false, then continue data transfer from the last error point // If full=true, then transfer all data func CopyTable(fromName string, toName string, full bool) error { // ... your code } If the `full=false` option is passed, the program should continue transferring data from the last error point. If `full=true`, it should transfer all data. **Basic level**: - sequential data transfer in 1 thread - recovery after failures (option `full=false`) Additional information: - if necessary, you can extend the interface by adding your methods - if necessary, you can use the **database/sql** package directly
/ * We need to transfer data from a source to a consumer. The source sends data in small batches (~ten records), while the consumer works more efficiently with large batches (~thousand records). A real example is transferring data from Kafka queues to a Clickhouse database. Source: - Conditionally infinite. - The source never returns more than MaxItems records per call to Next. - During one "session" (one call to Pipe), the source returns new data each time Next is called. - After restart, the source resumes from the last "confirmed" position, set by cookie. Therefore, *each* value of cookie returned by Next must be fixed after data is saved in the receiver, by calling Commit in the same order they were returned by Next. Receiver: - Cannot process more than MaxItems at once. Basic level: Implement a function func Pipe(p Producer, c Consumer) error that reads data from the source, groups it into a buffer of size no more than MaxItems, and saves it to the receiver, then fixes progress in the source. Complexity: Methods Next, Process, and Commit involve network calls and can take a long time. To speed up the transfer process, processes of reading, writing, and confirming progress should be parallelized. So that, when calling Process or Commit, reading from the source and forming a new buffer continue. * / const MaxItems = 9999 type Producer interface { // Next returns: // - batch of items to be processed // - cookie to be commited when processing is done // - error Next() (items []any, cookie int, err error) // Commit is used to mark data batch as processed Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }
Given a string of characters. Find the number of pairs of indices i and j (i <= j) between which, inclusively, there are no repeating characters. For the string "aba" the answer is 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") For the string "abcb" the answer is ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8
[name] pointed out a discrepancy in memory estimation: stated one thing, wrote another. How to correctly estimate memory?
Have you had experience working with distributed systems?
/* Given a string of characters. Find the number of pairs of indices i and j (i <= j) between which there are no repeating characters. For the string "aba" the answer is 5: can be not only ASCII [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */