• Как динамически отправлять данные на клиент с golang сервера?

    Eugene-Usachev
    @Eugene-Usachev
    Способов много. Можно использовать или SSE, или http2, или long Polling, или short Polling или Websockets. Причём последний вариант самый предпочтительный почти всегда, так как является очень популярным и шустрым. Замеры я не проводил, но на бумаге протокол Websockets имеет наименьший оверхед из всех способов. Реализаций Websocket очень много для Go.

    Если проект маленький, берите Gorilla-websocket, или fiber-websocket или fasthttp-websocket (зависит от того, какую библиотеку вы используете). Эти технологии очень простые и удовлетворяют почти всем требованиям. В крупных проектах я бы предложил использовать или centrifuge, или centrifugo. centrifuge - это хорошо оптимизированная библиотека, а centrifugo - готовое решение. Они посложнее, но уже оптимизированы и предоставляют fallbacks, если клиент не способен установить websocket.

    Если у вас есть специфичные требования, вам следует указать это, потому что сейчас приходится "тыкать в небо".
    Ответ написан
    Комментировать
  • Какой Road Way сделать чтоб прокачать навыки девопса под php разработку?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    ну изучи

    1. какую-то систему мониторинга, чтобы мог развернуть, настроить какие-то метрики и смотреть за ними. Возможно + графану для визуализации
    2. Какой-нить инструмент для CI (Jenkins, Gitlab CI...)
    3. Какой-нить инструмент для CD (можно реализовать на базе тех же Jenkins, Gitlab CI)
    4. собственно сам git и систему код ревью (Gitlab, Bitbucket, Github, Gerrit)
    5. системное администрирование на уровне установки и базовой настройки пакетов - все что вам нужно, типа кафки, раббит, elastic search и др
    6. bash маст хев для автоматизации установок. Питон на базовом уровня для простых вещей, возможно кусков мониторинга

    Ну и главное - инфраструктуру своего проекта, чтобы понимать от и до, как из исходников собирается и запускается проект.
    Ответ написан
    Комментировать
  • Почему так работают интерфесы в Го?

    Потому что в Го сигнатура метода в интерфейсе должна совпадать полностью. Таким образом на рантайме они быстро матчатся.

    Иначе пришлось бы заглядывать внутрь типа A, а так как это все происходит на рантайме, было бы неоптимально. Возможно для вашей цели больше подойдут дженерики, в их случае происходит мономорфизация и компилятор генерирует отдельный код для каждого варианта дженерика, что работает быстро.

    Кстати, не рекомендую называть интерфейсы ISomething, это не принято в Го.
    Ответ написан
    Комментировать
  • Можно ли (Как) установить модуль Golang из локального источника?

    @falconandy
    1. Можно включить вендоринг - тогда все зависимости будут размещены в подпапке vendor и при следующих сборках доступ в интернет не понадобится. go mod vendor
    2. Можно установить переменную GOPROXY так, чтобы исходники качались не через прокси proxy.golang.org, а через другой или напрямую с гитхаба. Environment variables
    3. Можно использовать уже скачанный локально репозиторий. replace directive in go.mod

    UPD: конкретно для go install можно попробовать п.2 с GOPROXY. Либо склонировать исходный репозиторий и собрать бинарник командой go build - для разрешения проблем с доступом к зависимостям воспользовавшись п. 1-3.

    UPD 2: по конкретно интересующему вас репозиторию: клонируете его, переходите в папку installer и выполняете в ней GO111MODULE=off go build, получите собранный бинарник - нет там никаких внешних зависимостей и даже go.mod
    Ответ написан
    1 комментарий
  • Как подсчитать размер фс включая место для самой фс?

    @xibir
    Ext4 создаёт таблицу inode'ов, эта таблица занимает несколько процентов от самого диска. Сколько конкретно сказать сложно, mkfs.ext4 вычисляет этот размер по какому-то своему алгоритму. Но этот размер можно зафиксировать через параметр -N для mkfs.ext4. Идиотские 5% можно тоже отключить через параметр -m (или после создания фс утилитой tune2fs). Например:
    truncate -s1g /tmp/disk
    mkfs.ext4 -Fm0 -N10000 /tmp/disk

    в файловой системе можно будет создать всего 10000 файлов

    А можно использовать xfs там проще и нету идиотских пяти процентов.
    Ответ написан
    1 комментарий
  • Как добиться корректной остановки postgres при остановке контейнера docker?

    chupasaurus
    @chupasaurus
    Сею рефлекторное, злое, временное
    В официальных образах postgres запускают в entrypoint с помощью gosu для корректного проброса сигналов, и через перезапуск баш-скрипта под юзером postgres, так что там 2 уровня глубины и все живы.
    Ответ написан
    Комментировать
  • Как защитить программу от копирования без интернета?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Никак. Единствнный способ гарантированно защититься от нелицензионного копирования - это вынести ключевую часть функционала на сервер. Любая остальная защита - лишь усложнение реверс инжениринга и взлома. Всегда можно каленым железом вырезать любую проверку ключа из исполняемого кода.

    Активация ключа по телефону/интернету исключает лишь самый тривиальный способ "взлома" - просто копирование одной и той же лицензии по куче компьютеров без модификации исполняемых файлов.

    А так, берете какую-нибудь крипто библиотеку, выдаете сертификат, в котором подписываете своим приватным ключем "Лицензия выдана ООО рога и копыта". В программе зашит ваш публичный ключ. Программа проверяет файл лицензии, что он подписан вашим ключем. Но любой "хакер" умнее вас просто вырежет эту проверку из программы.
    Ответ написан
    4 комментария
  • Как уменьшить время выполнения запроса like '%uri%' в Postgresql?

    iMedved2009
    @iMedved2009
    Не люблю людей
    1. GIN индексы - https://medium.com/@maanavshah/performance-optimiz...

    2. Через костыли: сделать составной индекс на url и на reverse(url) и искать как url like 'setting%' and reverse(url) like reverse('%setting')
    Ответ написан
    Комментировать
  • Готовая система папок?

    Stalker_RED
    @Stalker_RED
    С точки зрения вёрстки - это же просто список <ul> с иконками папок и ссылками. Вам вёрстка списка нужна?
    Со стороны бэкэнда - надо прочитать список папок и файлов в нужной директории, и отдать его в шаблонизатор. Все.
    Ответ написан
    Комментировать
  • Почему нельзя/можно писать бизнес-логику в sql?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Можно. Весь 20-й век почти так делали. База была главной. Эдакая себе царица. Ее любили. Холили.
    Приложения были двухзвенки. Оконная апликуха коннектилась к базе и все расчеты
    проводились в базе. Апликуха только показывала результаты в гридах и вводила формочки.
    Джобы тоже запускались в базе как процедуры на PL/SQL по скедулеру. Для пуска их клиент
    был тоже не нужен. Плановые задачи БД запускала самостоятельно. Это и было видение
    бизнес логики из 20-го века.

    В 21-м веке с развитием веба появился слой middle. И разработчики вынесли в него максимальную
    часть логики. Это произошло естественным путем. А базе досталась участь быть просто хранилищем
    таблиц. Потому что держать 2 копии логики или поддерживать было уже неудобно. В команде
    должен быть тогда разработчик и Java и PL/SQL одновременно. В современной парадигме
    разработки с ORM база стала просто чем-то вторичным. И на уровне ORM абстракций
    даже заменяемым на другие типы баз.

    Но не все так плохо.

    Фактически, логика современного приложения размазана по 3м слоям. Даже в браузере
    есть какая-то минимальная логика, например при аутентификации или при проверке
    валидности емейла. И какая-то логика агрегации (sum/group by) полюбому есть в базе.
    Потому что агрегировать в приложении все - глупо. Это лишний трафик.

    И нет такого архитектора который говорит "нельзя". Просто есть best-practices современной разработки,
    исходя из развитя железа, сетей и вообще рынка всего остального. Кто знает может в мобилах вернуться
    к двузвенкам. Смотря под каким углом смотреть на современные мобильные приложения? Who knows.
    Ответ написан
    2 комментария
  • Как сделать возможным вывод программы в консоль?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    если нужно в динамике - одновременно выводить на консоль, писать в файл и тут же сразу построчно анализировать поступающую информацию, то тут чуть сложнее, хоть и не немного, вот небольшой пример:
    работа через файл
    #!/usr/bin/env bash
    
    # функции бот1 и бот2 которые постоянно выводят рандомно числа от 0 до 9 с интервалом в 2 секунды
    bot1(){
    	while true; do
    		echo "Bot1: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    bot2(){
    	while true; do
    		echo "Bot2: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    # путь к лог-файлу куда будем писать логи от ботов
    LOG=/tmp/botsLog.txt
    
    # удаляем лог-файл (если ненужно то закоментирвоать)
    rm -rf $LOG
    
    # запускаем ботов в фоновом(&) режиме, 
    # а также начинаем выводит поступающую от них информацию на консоль и писать в общий лог-файл
    bot1 | tee -a $LOG &
    sleep 1
    bot2 | tee -a $LOG &
    
    # функция анализа лог-файла (потока)
    analysisLogs() {
    	# запускаем постоянное построчное чтение поступающих данных в функцию
    	while read -r data; do
    		# здесь мы задаём фильтры и то что выполнить если совпадёт условие
    		case "$data" in
    			"Bot1: 0" ) echo "Бот 1 выдал ноль"
    				;;
    			"Bot2: 0" ) echo "Бот 2 выдал ноль"
    				;;
    		esac
    	done
    }
    
    # tail выводит поступающие данные по мере роста лог-файла (мониторит)
    # в данном случае мы передаём появляющиеся данные из файла в функцию analysisLogs
    tail -f $LOG | analysisLogs 
    
    # это необходимо чтобы главная программа преждевременно не завершилась 
    # пока не завершаться запущенные в ней фоновые(&) потоки
    wait
    
    exit

    с комментариями думаю будет понятней
    ctrl+c завершить скрипт

    можно конечно и через переменную сделать но это будет не так красиво да и не по феншую, кстати здесь мы пишем в ОЗУ так как /tmp у большинства дистрибутивов примонтирован в оперативной памяти.

    Если же не хочется вообще писать данные на диск или в озу, так как логи обычно склонны к накоплению если их не чистить да или просто ненужны, то можно просто использовать именованный канал(FIFO-файлы) с которым можно работать как с файлом(читать/писать) но при этом он будет выступать просто в роли промежуточного буфера, для этого в нашей программе нужно поменять всего две строчки(создать именованный канал и вместо tail использовать обычный cat )
    работа через fifo-файл
    #!/usr/bin/env bash
    
    # бот1 и бот2 просто постоянно выводят рандомно числа от 0 до 9 с интервалом в 2 секунды
    bot1(){
    	while true; do
    		echo "Bot1: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    bot2(){
    	while true; do
    		echo "Bot2: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    # путь к лог-файлу куда будем писать логи от ботов
    LOG=/tmp/botsLog.txt
    
    # удаляем лог-файл
    rm -rf $LOG
    
    # создаём именованный канал (FIFO-файл)
    mkfifo $LOG
    
    # запускаем ботов в фоновом(&) режиме, 
    # а также начинаем выводит поступающую от них информацию на консоль и писать в общий fifo-файл
    bot1 | tee -a $LOG &
    sleep 1
    bot2 | tee -a $LOG &
    
    # функция анализа поступающих данных
    analysisLogs() {
    	# запускаем постоянное построчное чтение поступающих данных в функцию
    	while read -r data; do
    		# здесь мы задаём фильтры и то что выполнить если сработает условие
    		case "$data" in
    			"Bot1: 0" ) echo "Бот 1 выдал ноль"
    				;;
    			"Bot2: 0" ) echo "Бот 2 выдал ноль"
    				;;
    		esac
    	done
    }
    
    # читаем файл(FIFO-файл) и передаём появляющиеся данные в функцию analysisLogs
    cat $LOG | analysisLogs 
    
    # это необходимо чтобы главная программа преждевременно не завершилась 
    # пока не завершаться запущенные в ней фоновые(&) потоки
    wait
    
    exit
    Ответ написан
    1 комментарий
  • Какие есть коллекции словарей, какие посоветуете библиотеки?

    GavriKos
    @GavriKos
    1000 - 10000 ключей - не те объемы, на которых нужна оптимизация словаря - все там будет быстро.
    А для реально больших количеств ключей используются базы данных
    Ответ написан
    Комментировать
  • Как найти работу со сложными и комплексными проектами если нету опыта работы в таких проектах?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    У большинства программистов первое рабочее место - это унылая маленькая компания с примитивными технологиями и простыми задачами. Следующая работа немного лучше. Следующая ещё лучше. И так пока не заберëшься на максимально доступную тебе высоту. Потолок и скорость развития у всех разные, зависят в основном от того, на сколько сильно стараешься. Некоторые так никогда и не выбираются из эникейщиков и крутильщиков cms'ок. Немало тех, кто выбирается лет десять.
    Ответ написан
    Комментировать
  • Что быстрее SQL или Javascript?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Мужские мужчины уже ответили на основной вопрос.

    Я добавлю что чем больше данных мы обрабатываем тем дороже становиться цена передчи
    информации из места где оно храниться в блок вычислений. В концепции трехзвенки которая
    описана RDS(Postgres)/NodeJS/Python/Web удобнее всего вычилсять прямо в Postgres. Поскольку
    данные рядом и сетевых расходов на передачу нет. Если Postgres по каким-то причинам не может
    вычислять или не владеет API то в этом случае мы с помощью курсора (SELECT) передаем
    нужный датасет на клиента (в данном случае это Python/Node) и там вычисляем. При этом
    мы должны понимать что это займет время и сетевой канал да еще и результат вычислений
    тоже надо отослать обратно. Тоесть данные будут бегать как рейсовый автобус туда-сюда.

    Для однозначного решения что хорошо и что плохо - надо ставить эскперимент. Но предварительно
    мне и присуствующим уже очевидно что лучше всего вычислять прямо в хранимых процедурах
    Postgres. Единственным доводом против может быть несовершенство языка PL/pgSQL
    но я-бы этот факт тоже проверил. Для реляционных задач его обычно хватало.

    Данная проблема (рейсовый автобус для данных) еще более сильно выражена в BigData. Там стараются
    дизайнить систему так что данные - write-only и после загрузки в хранилище (ETL/ELT) больше никогда
    не изменяются и лежат неподвижно (т.н. Bronze Level информации). И джобы которые бегают
    по ним - запускаются в вычислительном кластере физически рядом с дисковым хранилищем.

    Вот. А на клиента отдаются обычно сводные отчеты и кака-то аналитика. Это то что в 100-10000 раз меньше
    по размеру обычно чем основные данные.
    Ответ написан
    Комментировать
  • Можно ли в структуре указать тип данных отличный от того что лежит в базе данных?

    Хорошей практикой является принимать данные из БД в структуру, которая соответствует по типам тому, что лежит в БД.

    Если вам нужно конвертировать потом эти данные, конвертируйте их в другую структуру, которая расположена на слое бизнес-логики, например.
    Ответ написан
    2 комментария
  • Хорошая ли стратегия разбивать монолит джанго на микросервисы джанго?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Смотри. Уже прошло время когда все пилили монолиты на микросервисы. Щас пошло переосмысление.
    Объективно есть 2 причины пилить. Первое - организационная. Команда по какой-то причине не хочет
    или не может поддерживать приложение. Или там что-то с бизнесом. Слияние. Поглощение. Передача
    проекта другой команде в поддержку. Тогда берут и ставят задачу раздела отвественностей.
    Конвей про это писал еще.

    И второе - это баланс нагрузки и децентрализация. Про failover тут еще даже речи нет. Это
    тяжелая тема и распилить монолит так чтобы его части были отказоустойчивы очень трудно. Более
    того в случае синхронных взаимодействий между частями микросервисов может быть даже падение
    перформанса
    . Да. Теоретики которые там пишут восторженные отзывы - совершенно игнорируют
    накладные на RPC. И не упоминают что в монолите цена RPC была равна нулю. Иногда RPC заменяют
    на MQ - но это новая архитектура и это надо полностью переделывать бизнес.

    И что делать с базой данных? Это тот еще вопрос. Я почти готов спорить что вы базу пилить не будете.
    И что в результате будет? Иммитация микро-сервисов? Где слабая связность?

    Тоесть если у вас нет таких кричащих ситуаций что оргазниация требует или нужно баланс
    нагрузки как-то разнести - то тебе вообще-вообще нет смысла ходить ни в какие микросервисы.

    Но имеет смысл сделать модуляризацию монолита. Например что там...
    application
    - sales
    - hiring
    - userprofiles

    Тоже очень полезно для управления сложностью. И пускай себе будет монолит зато будет сильный
    контроль за изменениями.
    Ответ написан
    6 комментариев
  • На что опираться при выборе изучения RN и Flutter?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    кол-во вакансий у RN в раза 2-3 выше

    Это.
    Ответ написан
    Комментировать
  • Как разбить строку через разделитель несколько раз?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    $result = preg_replace('~^(.{8})(.{4})(.{4})(.{4})(.*)~', '$1-$2-$3-$4-$5', $str);
    Ответ написан
    Комментировать
  • Разделение ответственности или производительность?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Мне кажется, что все прочитали только заголовок, а на текст поста никто не обратил внимания. Как обычно
    А там-то и лоснится самый ЖЫР:

    Но в этом случае мне придется выполнить 2 запроса к базе данных

    То есть вся "проблема" тут из-за каши в голове клиента, который откуда-то взял, что во втором варианте у него будет не два запроса, а один. Ну то есть понятно откуда - очередной разрабончик баз данных, который SQL видел только в кино, а база данных для него - это вот это вот prisma create.

    И только из-за этих нелепых страхов он ломает всю логику и сервис юзеров у него начинает лазить в БД постов. Что и является здесь проблемой. А не какие-то, опять же, дурацкие страхи про дублирование вызова нотификации.
    Ответ написан
    6 комментариев
  • Как происходит исполнение кода в Event Loop и управление потоками для веб приложений?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    1. Как происходит связь между кодом js, c++. На самом гитхабе Nodejs можно открыть папки с функциями, которые я импортирую в коде. А также их реализации в файлах .cc расширения. Но не могли бы подробнее описать механизм, которые позволяет 2 разных языка использовать.
    JS движок (например V8) предоставляет платформе (Node.js) некоторый C++ api, через который платформа может движком управлять. Например через это api можно дать движку строчку с JS кодом и попросить его выполнить, а в ответ получить указатель на результат выполнения (V8 например возвращает результат последнего выражения в коде). Так же, если у нас есть указатель на JS функцию, можно попросить движок ее выполнить с определенными аргументами и this, а в ответ получить результат этого выполнения (функция что-то вернула или бросила исключение). Ну и наконец, мы можем дать этому api указатель на C/C++ функцию, а движок сделает из нее JS функцию и вернет указатель на нее, когда JS функция вызывается движок вызовет нашу C/C++ функцию и даст ей на вход контекст выполнения, из которого можно извлечь this и аргументы функции, так же через контекст можно установить результат выполнения JS функции, указав что JS функция должна вернуть некоторое JS значение или бросить некоторое исключение.

    2. V8 - движок для исполнения JS кода, то есть превращения его в машинный код для исполнения комманд. Libuv написана на с++. Они же не работают в паре? Я так понимаю, что часть кода исполняется на движке v8, а различные асинхронные вызовы, которые через Nodejs api делегируются библиотеке Libuv - уже от неё превращаются в низкоуровневый машинный код, который исполняется компьютеров?Можете чуть пролить свет на исполнения уже между этими компонентами Libuv, V8.
    V8 ничего не знает о libuv, как и libuv ничего не знает о V8.
    V8 занимается компиляцией/интерпретацией/выполнением JS кода, управлением JS памятью и некоторыми другими связанными с JS вещами. В V8 нет никаких event loop и чего-то подобного, он запускает JS код только когда ему об этом скажет платформа (например Node.js).
    Libuv занимается асинхронными операциями. Что-то переадресует операционной системе, например сетевые сокеты можно собрать в пачку и отдать в epoll в Linux или kqueue в MacOS, заблокировав лишь один поток сразу на тысячи сокетов. А что-то просто блокируется на фоновых потоках, например обращения к файловой системе. Event loop нет и здесь, но зато есть очередь задач, которые потенциально готовы.
    Ну и наконец сама платформа (Node.js) реализует event loop (по сути просто бесконечный цикл), в котором получает потенциально готовые задачи от libuv и раскладывает по своим очередям готовые, а неготовые планирует в libuv, спрашивает у V8 не хочет ли он сделать сборку мусора, ну и наконец говорит V8 вызвать некоторые JS функции.

    3. После того, как Nodejs передает асинхронный вызов Libuv на исполнение. То callback функция помещается позже в стэк для исполнения, а исполнятся начинается после того, как система просигнализирует о завершении процесса, например считывания файла. Или вначале считывается файл, а потом система об этом сигнализирует и помещается callback функция в стэк Event Loop'a для исполнения?
    Выше уже расписал как Node.js взаимодействует с libuv в теле event loop, так же расписал как JS код может вызвать C++ функцию. Рассмотрим на сильно упрощенном примере, что происходит когда в JS коде на Node.js мы вызываем fs.readFile(filepath, callback):
    1. fs.readFile - это обычная JS функция, но внутри она вызывает некоторую C++ функцию из Node.js, которая получает указатель на строку filepath и указатель на JS функцию callback, но эта C++ функция будет запущена на том же потоке где и event loop (по сути где-то внутри цикла), а блокировать нам нельзя. Поэтому она просто планирует вызов другой C++ функции на фоновых потоках и завершается, возвращая тем самым управление JS коду.
    2. В какой-то момент до запланированной C++ функции дойдет очередь на выполнение на одном из фоновых потоков, она прочитает файл в память и добавит в очередь готовых задач некоторый объект, который является результатом операции чтения из файла, этот объект будет хранить в себе указатель на прочитанные данные и указатель на JS функцию callback.
    3. Еще через некоторое время поток с event loop извлечет из очереди этот объект результат и скажет V8 вызвать функцию callback с данными из файла.

    4. Можете более подробней рассказать про исполнение кода на инстансах приложения в зависимости от количества ядер процессора и управления потоками:

    4.1 Есть к примеру приложений на Nodejs. На компьютере 4 ядра. Я на каждом ядре могу запустить инстанс этого приложения. И у каждого инстанса в pool thread'e будет по 4 потока дополнительных, которые создаются по умолчанию?
    Каждый инстанс Node.js - это отдельный процесс операционной системы. У каждого процесса своя изолированная память. И да, каждый может запускать несколько потоков (у Node.js кстати 4 потока - это минимум, при большой нагрузке она может добавить в пул до 128 потоков), но в случае с Node.js большая часть потоков почти всегда что-то ждут (пока тот же файл прочитается например) и почти не тратят ресурсы CPU, а активно работает лишь один - тот в котором event loop.

    4.2 Если отойти от ноды и запустить приложение на php фреймворке на Apache и этот сервер выделяет под каждый запрос свой поток.В данном случае - это такой же условно поток, который может выделяться и библиотекой Libuv или это абсолютно разные понятия? И сколько инстансов php приложения запущено, когда Apache под каждый создает свой поток? Как соотносится поток с инстансом приложения на php.
    С точки зрения операционной системы - да, это такие же потоки. Разница заключается в том, что в этих потоках происходит. В php только 1 поток, который то что-то полезное делает, то ждет ответа от БД/файловой системы/еще чего-то. А в Node.js это разделено, 1 поток занят только полезной работой (выполнением JS кода) и несколько только ждут ответа.
    Насчет какие там лимиты на количество инстансов php у Apache я не скажу, но они точно не бесконечные, а значит если лимит будет исчерпан, то клиенты (браузер) будут ждать пока какой-то из инстансов php не завершит свою работу полностью. А в node.js мы на одном инстансе можем обслуживать сразу множество клиентов, выполняя задачи для каждого по чуть-чуть, пока для одного клиента ждем ответ из БД можем заняться обработкой запроса от другого клиента.

    4.3 Может в дополнение расскажите про потоки в системе, их ограничения и т.д
    Тут целую лекцию можно читать. Думаю это стоит вынести в отдельный вопрос.
    Ответ написан
    3 комментария