Sobes.tech

Имали ли сте опит с разпределени системи?

215

Дадена е низ от символи. Намерете броя на двойките индекси i и j (i <= j), между които, включително, няма повтарящи се символи. За низа "aba" отговорът е 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") За низа "abcb" отговорът е ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8

213

Какви са разликите между средата local, dev, stage, prod?

213

/* Дадена е низ от символи. Намерете броя на двойките индекси i и j (i <= j), между които няма повтарящи се символи. За низа "aba" отговорът е 5: може да не са само ASCII [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */

213

/* Трябва да прехвърлим данни от източник към потребител. Източникът предоставя данни на малки пакети (~десет записа), докато потребителят работи по-ефективно с големи пакети (~хиляда записа). Реален пример е прехвърлянето на данни от опашки тип Kafka към база данни Clickhouse. Източник: - Практически безкраен. - Източникът никога не връща повече от MaxItems записи при едно извикване на Next. - В рамките на една "сесия" (едно извикване на функцията Pipe), източникът при всяко Next връща нови данни. - След рестарт обаче, източникът започва от предишната "потвърдена" позиция, указана от cookie. Затова, всяка стойност cookie, върната от Next, след като данните са запазени в получателя, трябва да бъде потвърдена с извикване на Commit, в същия ред, в който са били върнати от Next. Получател: - Не може да обработи повече от MaxItems наведнъж. Базово ниво: Трябва да се реализира функцията func Pipe(p Producer, c Consumer) error, която чете данни от източника, ги групира в буфер с размер не по-голям от MaxItems и ги запазва в получателя, след което потвърждава напредъка в източника. Усложнение: Методите Next, Process и Commit са свързани с мрежови извиквания и могат да отнемат доста време. За ускоряване на процеса, трябва да се паралелизират процесите по четене, запис и потвърждаване на напредъка. Така, че по време на Process или Commit, четенето от източника и формирането на новия буфер да продължават. */ const MaxItems = 9999 type Producer interface { // Next връща: // - пакет от елементи за обработка // - cookie за потвърждение, когато обработката е завършена // - грешка Next() (items []any, cookie int, err error) // Commit се използва за маркиране на пакет данни като обработени Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }

213

Обяснете принципа на инверсия на зависимостите и защо директното извикване на методи на репозитория от use case нарушава SOLID.

212

Разкажи за базите данни — с какви си работил и с какви работиш сега?

212

Как сте извършили тестиране и проверка на коректността на изпълнените заявки?

Junior — Middle
211

/* Има приложение с микросервисна архитектура. Микросервисът може да бъде абстрахиран чрез интерфейса Backend. За достъп до една инстанция на микросервиса може да се използва типът BackendImpl, който вече е реализиран. Всеки микросервис има няколко десетки работещи инстанции, всяка от които е достъпна по свой адрес addr. Обаче, отделните инстанции на микросервиса не са надеждни: те могат да се сринат, да са недостъпни или претоварени. Затова трябва да реализирате тип Balancer, който също реализира интерфейса Backend и извършва балансировка на натоварването от страна на клиента между инстанциите на микросервиса, като избира всеки път **най-малко натоварената** инстанция. */

210

Как JWT проверява своята автентичност? Как се удостоверява, че токенът не е фалшифициран?

210

/* Има приложение с архитектура на микросервизи. Микросервис може да бъде абстрахиран чрез интерфейса Backend. За достъп до инстанция на микросервиса, може да използвате типа BackendImpl, който вече е реализиран. Всеки микросервис има няколко десетки работещи екземпляра, всеки от които е достъпен по свой адрес addr. Обаче отделните екземпляри на микросервиса не са надеждни: те могат да се сринат, да бъдат недостъпни или претоварени. Затова трябва да реализирате типа Balancer, който също реализира интерфейса Backend и извършва баланс на натоварването от страна на клиента между екземплярите на микросервиса, като всеки път избира **най-малко натоварения** екземпляр. */ type Request interface{} type Response interface{} type Backend interface { Invoke(ctx context.Context, req Request) (Response, error) } var _ Backend = &BackendImpl{} // addr съдържа ip:port на конкретен екземпляр func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs съдържат адресите на всички балансирани екземпляри func NewBalancer(addrs []string) *Balancer { // TODO }

209

Имали ли сте опит в управлението на екип?

208

Какво е ограничението на семафора и буферирания канал като решения за ограничаване на паралелните заявки?

208

Какво се добавя към отговора, когато прозорецът стане валиден?

207

Как да сравняваме елементи в карта? Как да проверим дали две карти съвпадат?

205

Какъв е максималният брой заявки в секунда (RPS), който е обработвал най-натовареният сервиз?

204

Напишете задача на езика Go — практичен раздел (проблеми от живота на разработчика, без алгоритми): доработете или поправете услуга. Продължителност — 1,5 часа.

204

Формат на работа: дистанционно, в офиса или хибриден?

203

Как да направите паметта постоянна (да премахнете зависимостта от броя на уникалните символи)?

203
/11