Какой опыт работы с сетевым программированием и используемые библиотеки
Что проверяют
Понимаете ли вы, что происходит под обёрткой библиотеки: сокеты, блокирующий и неблокирующий ввод-вывод, мультиплексирование. Следом просят набросать схему асинхронного сервера или рассказать, как вы обрабатывали частичное чтение и обрыв соединения.
Как отвечать
Каркас такой: на каком уровне работали, какая модель ввода-вывода, какие библиотеки, одна история.
- сокеты BSD:
socket,bind,listen,accept,recvиsend.recvможет вернуть меньше байт, чем запрошено, поэтому границы сообщений в TCP размечают сами: длиной в заголовке или разделителем; - мультиплексирование:
selectиpollдля небольшой нагрузки,epollв Linux,kqueueв BSD и macOS, IOCP в Windows,io_uringв свежих ядрах Linux; - Boost.Asio или standalone Asio:
io_context, асинхронные операции с обработчиками,strandдля последовательного выполнения обработчиков без мьютекса, корутины C++20 черезco_spawnиuse_awaitable. Networking TS в стандарт так и не вошёл; - Boost.Beast: HTTP и WebSocket поверх Asio;
- TLS: OpenSSL напрямую или
ssl::streamиз Asio; - другие: libuv, libevent, gRPC, Poco для HTTP-клиента, ZeroMQ для обмена сообщениями.
Потом один проект: протокол, число соединений, как решили проблему медленного клиента и переполнения буферов, как искали утечку дескрипторов. Цифры давайте свои и с условиями замера. Если опыт в основном учебный, скажите это и опишите, что написали сами: эхо-сервер на epoll, чат на Asio, какие ошибки поймали и как.
Где спотыкаются
Считают, что один recv на приёме соответствует одному send на передаче. TCP это поток байтов, границ сообщений он не хранит.
Путают асинхронность с многопоточностью: заводят поток на каждое соединение и называют это масштабируемым сервером. На десятках тысяч соединений это упирается в память и переключения контекста.
Забывают про время жизни объектов в асинхронном коде: сессия уже удалена, а её обработчик ещё стоит в очереди. В Asio это решают через shared_from_this: обработчик захватывает shared_ptr на сессию.