Have you had experience working with distributed systems?
Golang
/ * 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
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
/* 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") */
/ * 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 }
Explain the principle of Dependency Inversion Principle and why directly calling repository methods from use case violates SOLID.
Tell about databases — what have you worked with and are currently working with?
How did you perform testing and verification of the correctness of the executed requests?
What are the differences between local, dev, stage, and prod environments?
/ * There is an application with a microservices architecture. A microservice can be abstracted using the Backend interface. To access a single instance of a microservice, you can use the BackendImpl type, which is already implemented. For each microservice, there are several dozen running instances, each accessible via its own address addr. However, individual instances of the microservice are unreliable: they can crash, be unavailable, or overloaded. Therefore, you need to implement a type Balancer, which also implements the Backend interface and performs client-side load balancing among the microservice instances, choosing the **least loaded** instance each time. */
How does JWT verify its authenticity? How is it ensured that the token is not forged?
/ * There is an application with a microservices architecture. A microservice can be abstracted using the Backend interface. To access a single instance of a microservice, you can use the BackendImpl type, which is already implemented. Each microservice has several dozen running instances, each accessible via its own address addr. However, individual instances of the microservice are unreliable: they can crash, be unavailable, or overloaded. Therefore, you need to implement a Balancer type that also implements the Backend interface and performs client-side load balancing among the microservice instances, choosing the **least loaded** instance each time. */ type Request interface{} type Response interface{} type Backend interface { Invoke(ctx context.Context, req Request) (Response, error) } var _ Backend = &BackendImpl{} // addr contains the ip:port of a specific instance func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs contain the addresses of all balancable instances func NewBalancer(addrs []string) *Balancer { // TODO }
Have you had experience managing a team?
What is the limitation of a semaphore and a buffered channel as solutions for limiting parallel requests?
What is added to the response when the window becomes valid?
How to compare elements in a map? How to check if two maps match?
What is the maximum number of requests per second (RPS) that the most high-load service has processed?
Write a task in Go — practical section (real-life developer tasks, no algorithms): improve or fix a service. Duration — 1.5 hours.
Remote, office, or hybrid work format?
How to make memory constant (remove dependency on the number of unique characters)?