DNK_C_C++_Go_Rust
45 subscribers
14 photos
45 links
DNK - дневник кодера С и С++
Download Telegram
#513_ADM_DvOp_TOS

За что отвечает процесс с PID = 0?

Процесс с номером PID = 0называется процессом нулевого уровня и обозначается swapper или scheduler.
Этот процесс является виртуальным процессом ядра операционной системы и отвечает за:
— Планирование задач (scheduling) и переключение между потоками выполнения.
— Управление памятью и
свопингом страниц («swapping») между оперативной памятью и диском, когда память занята.
— Внутреннее обслуживание и координацию потоков внутри ядра.

Фактически, этот процесс представляет ядро самой ОС, которое само себя регистрирует при старте системы и постоянно выполняется на фоне всех остальных процессов.
Поскольку он зарезервирован за самим ядром, обычные пользователи не имеют доступа ни к нему, ни к его управлению.


Процесс с PID = 0 является неотъемлемой частью функционирования ядра Linux и обеспечивает базовую инфраструктуру планирования задач и распределения ресурсов.
🔥1
#514_ADM_DvOp_TOS

С помощью чего общаются процессы в Linux?

Процессы в ОС Linux могут взаимодействовать друг с другом различными способами.


Основные методы межпроцессного взаимодействия (IPC — Inter Process Communication):


1. Каналы (Pipes)простейший способ связи между процессами — каналы.
Каналы бывают двух видов:

— Анонимные каналыиспользуются для передачи данных между родителем и дочерними процессами.
Именованные каналы (FIFO)позволяют обмениваться информацией между произвольными процессами, даже если они запущены разными пользователями.

2. Сигналы (Signals)асинхронное уведомление процессов об определенных событиях.
Например, сигнал SIGTERM используется для завершения процесса, SIGKILL принудительно прекращает выполнение программы.

3. Разделяемая память (Shared Memory)процессы могут совместно использовать область памяти, что позволяет быстро передавать большие объемы данных.

4. Сообщения (Message Queues)механизм отправки сообщений от одного процесса другому через очередь сообщений ядра ОС.

5. Семафоры (Semaphores)используются для синхронизации действий нескольких процессов.
Они помогают предотвратить одновременный доступ разных процессов к общим ресурсам.

6. Socket-файлы (Unix Domain Sockets)позволяют осуществлять передачу данных между процессами внутри одной системы посредством файлов сокетов.

7. FIFOs (Named Pipes)аналогично именованным каналам, обеспечивают двунаправленную связь между двумя процессами.


Эти механизмы широко применяются в различных приложениях Unix-подобных ОС, включая Linux, обеспечивая гибкость и эффективность межпроцессного взаимодействия.
#515_ADM_DvOp_TOS

Сигналы SIGINT, SIGTERM, SIGHUP, SIGKILL в Linux?


1. SIGINT (Signal Interrupt)посылается процессу, когда пользователь нажимает комбинацию клавиш Ctrl+C.
Обычно обрабатывается процессом для плавного прекращения своей работы. По умолчанию вызывает завершение процесса.

Пример: программа читающая ввод с клавиатуры, прерываемая нажатием Ctrl+C, должна завершить свою работу аккуратно, сохранив состояние или завершив активные операции.


2. SIGTERM (Signal Terminate)cамый распространенный сигнал для завершения процесса. Часто отправляется командой kill с параметром по умолчанию (kill <PID>).
Обрабатывая этот сигнал, приложение имеет возможность очистить ресурсы перед завершением. Если игнорируется или блокируется, процесс продолжает выполняться.
Используется для мягкого завершения процессов, позволяя завершить активность плавно.


3. SIGHUP (Signal Hangup)изначально отправлялся терминалом при разрыве соединения (например, закрытии сессии SSH).
Сейчас часто используется для перезагрузки конфигураций приложений.
Многие демоны и серверы реагируют на этот сигнал путем перезагрузки конфигурации без остановки службы.
Иногда также применяется для полного завершения приложения, аналогично
SIGTERM.


4. SIGKILL (Signal Kill)не перехватывается и не игнорируется ни одним процессом.
Остановка осуществляется немедленно, независимо от состояния обработки сигналов.
Посылка
SIGKILL останавливает процесс сразу же, без возможности очистки ресурсов (закрытия файлов, освобождения памяти и т.п.).
Запускается командой kill -9 <PID>. Применяется, когда обычные сигналы не приводят к остановке процесса (например, зависания или блокировки).


Каждый из этих сигналов играет важную роль в управлении поведением процессов в Linux.
Правильное использование сигналов помогает контролировать поведение приложений, обеспечивать аккуратное завершение работы и восстановление ресурса.
#516_ADM_DvOp_TOS

Что такое Load average?

Load Averageметрика производительности Unix-подобных ОС (Linux, FreeBSD), отражающая среднюю нагрузку процессора за определенный промежуток времени.
Показывает количество процессов, ожидающих выполнения на CPU, включая процессы в состоянии ожидания ввода-вывода (I/O wait).


Как рассчитывается?
Обычно выводится три значения нагрузки средней за промежутки времени:
За последнюю минуту (loadavg_1min)
За последние пять минут (loadavg_5min)
За последние пятнадцать минут (loadavg_15min)

Эти показатели помогают оценить, насколько загружены ресурсы системы и стабильна ли нагрузка во времени.

Например, команда uptime выводит load average следующим образом:
$ uptime
17:30:01 up 8 days, 3 hours, 2 users, load average: 0.15, 0.21, 0.25


Здесь:
0.15 — средняя загрузка за последнюю минуту,
0.21 — за последние пять минут,
0.25 — за последние пятнадцать минут.


Интерпретация значений.
Значение меньше единицы (например, 0.5) — система практически простаивает и свободна для новых задач.
Значение около единицы (например, 1.0)процессор загружен примерно на полную мощность одним процессом.
Большее значение, особенно значительно превышающее число ядер процессорасигнализирует о перегрузке системы (задержки, очереди задач).
Например, если у вас двухъядерная машина, а load average больше 2.0, это повод задуматься о снижении нагрузки.


Load Averageпомогает оперативно оценивать состояние загрузки сервера и вовремя реагировать на возможные проблемы производительности.
#517_ADM_DvOp_TOS

Как можно уберечь процесс от OOM-killer?

OOM-Killer (Out Of Memory Killer) механизм ядра Linux, предназначенный для аварийного завершения процессов в ситуации критической нехватки оперативной памяти.
Чтобы защитить важные процессы от убийства OOM-Killer'ом, можно предпринять следующие шаги:

1. Настройка параметра oom_score_adjкаждому процессу присваивается значение oom_score, которое определяет вероятность выбора процесса для уничтожения.
Чем выше этот показатель, тем вероятнее, что именно этот процесс станет жертвой OOM-Killer'a.
Можно вручную снизить вероятность для важных процессов путем изменения значения /proc/<PID>/oom_score_adj.

Значение oom_score_adj варьируется от -1000 до 1000:
-1000 — защищает процесс от убийств.
1000 — делает процесс наиболее привлекательным кандидатом для убийства.

Пример защиты процесса с PID=1234:
echo "-1000" > /proc/1234/oom_score_adj


Также, начиная с версии ядра 2.6.11, существует специальный флаг OOM_DISABLE (-17) для полной защиты процесса от убийств.
Пример настройки флага:
echo "-17" > /proc/1234/oom_score_adj



2. Использование системных переменных cgroupsконтейнеризация процессов позволяет ограничить потребление памяти отдельным приложением, что снижает риск возникновения OOM ситуаций глобально для всей системы.
Создавая группу контроля (cgroups), можно установить лимиты на доступную память.

Примеры ограничений:
# Создание группы control group
mkdir /sys/fs/cgroup/memory/myapp
# Установка лимита памяти для группы myapp (например, 1GB)
echo "1073741824" > /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes
# Перемещение процесса в новую группу
echo "<PID>" > /sys/fs/cgroup/memory/myapp/tasks


Это позволит предотвратить чрезмерное потребление памяти одним процессом и избежать активизации OOM-Killer'a.


3. Оптимизация приложениянаиболее эффективный способ избежать OOM-Killer заключается в предотвращении утечек памяти и улучшении архитектуры приложений:
Мониторинг потребления памяти вашим приложением.
Профилирование и устранение утечек памяти.
Правильное управление памятью и освобождение неиспользуемых объектов.



4. Увеличение объема доступной памятииногда проще увеличить физическую оперативную память серверов или расширить область свопа, чтобы избежать исчерпания доступной RAM.
Однако злоупотребление swapping ухудшает производительность, поэтому лучше искать баланс между объемом ОЗУ и оптимизацией приложений.


5. Для сервиса, который управляется через systemd, есть возможность указать специальную опцию в systemd-unit файлеиспользование специальных опций systemd:
Сервисы, управляемые через systemd, могут указывать специальные опции в unit-файлах, такие как OOMScoreAdjust.
Эта настройка позволяет регулировать приоритет процесса относительно OOM-killer.

Пример конфигурации:
[Service]
OOMScoreAdjust=-1000


6. Записать определенное значение по пути /proc/{PID}/oom_adjкаждый процесс имеет настраиваемый параметр, определяющий его приоритет для OOM-killer.
Путем записи отрицательного значения в файл /proc/{PID}/oom_adj можно снизить вероятность выбора процесса для убийства.
Однако, начиная с ядра 2.6.36, рекомендуется использовать новый интерфейс /proc/{PID}/oom_score_adj, поддерживающий диапазон от -1000 до 1000.


Комбинируя изменение настроек OOM-киллера, ограничение потребления памяти через cgroups и профилирование ПО, можно существенно уменьшить шансы потерять важный процесс из-за нехватки памяти.
#518_ADM_DvOp_TOS

Какие типы записей хранятся в /etc/fstab?

Файл /etc/fstab — предназначен для хранения настроек автоматического монтирования файловых систем Linux при загрузке системы либо вручную командой mount.


Типичные записи в /etc/fstab.

Каждая запись состоит из шести полей, разделённых пробелами или табуляциями. Формат строки выглядит следующим образом:
<устройство> <точка_монтирования> <тип ФС> <опции> <dump> <pass>


Поля:
Устройство путь к устройству (например, /dev/sda1) или UUID устройства (UUID=...), метка диска (LABEL=...) или сетевой ресурс:
/dev/sdb1
UUID=f8a7c2b9-b2d5-42cd-a4f7-e7227054a678
LABEL=data_disk
//server/share


Точка монтированиякаталог, куда монтируется файловая система:
/mnt/data
/home/user


Тип файловой системытип используемой файловой системы (ext4, xfs, btrfs, ntfs, vfat и др.):
ext4
xfs
btrfs
swap
cifs
nfs
tmpfs
proc
sysfs
devtmpfs


Опции монтированиядополнительные опции для настройки поведения файловой системы при монтировании (например, права доступа, режим чтения/записи).
Некоторые часто используемые опции:
defaultsстандартные значения (rw, suid, dev, exec, auto, nouser, async)
roдоступ только для чтения
noexecзапрет запуска исполняемых файлов
nosuid игнорирование setuid/setgid флагов
_netdevустройство является сетевым ресурсом

Dump поле используется программой резервного копирования dump. Обычно имеет значение 0.
Passпорядок проверки файловой системы утилитой fsck. Значение 0 означает отсутствие проверки, 1 для корневой файловой системы, 2 для остальных.


Общие типы записей:

Локальные блочные устройства (HDD/SDD):
/dev/sda1     /               ext4      defaults       0          1


RAM-диски и временные файловые системы:
tmpfs           /run            tmpfs     mode=0755,nosuid,nodev,size=10% 0       0


SWAP-разделы:
/dev/sdc1       none            swap      sw                0       0


Сетевые ресурсы (NFS/CIFS):
//nas.example.com/home /mnt/nas_home cifs credentials=/root/.smbcreds,_netdev,rw,user 0 0


В /etc/fstab хранятся различные типы записей, определяющие правила монтирования локальных устройств, виртуальных ресурсов и сетевых хранилищ.
#519_ADM_DvOp_TOS

Что такое runlevels в Linux?

Runlevels («уровни исполнения») в Linuxразные состояния ОС, определяющие набор активных служб и демонов.
Каждый уровень определяет специфическое состояние системы и соответствующий набор сервисов, необходимых для функционирования в данном режиме.

Традиционно в классических дистрибутивах Linux (таких как Debian, Ubuntu до версии 15.04, CentOS/RHEL версий ниже 7.x) существовало семь уровней исполнения (от 0 до 6).
Однако начиная с появления systemd в большинстве современных дистрибутивов концепция runlevels была заменена единицами (units), хотя традиционная нумерация уровней всё ещё поддерживается ради обратной совместимости.

Oсновные традиционные уровни исполнения в Linux:
Уровень  Описание
0 Выключение компьютера
1 Однопользовательский режим
2–5 Много-пользовательские режимы
6 Перезагрузка компьютера



Подробности каждого уровня:
Уровень 0: Полное выключение системы.
Уровень 1: Система запускается в однопользовательском режиме, предназначенном преимущественно для обслуживания и устранения неполадок. Доступ ограничен одним администратором, графический интерфейс отсутствует.
Уровни 2–5: Стандартные много-пользовательские режимы, доступные пользователям одновременно. Уровни отличаются уровнем предоставляемых услуг.
К примеру, в некоторых системах:
Уровень 2 базовая сеть и службы;
Уровень 3 — полный многопользовательский режим с сетью;
Уровень 4 — зарезервирован и редко используется;
Уровень 5 — полная многозадачная среда с возможностью запуска X Window System (графического интерфейса).
Уровень 6: Перезагрузка системы.

Современные дистрибутивы используют систему инициализации systemd, которая позволяет гибко управлять сервисами независимо от традиционного разделения на runlevels.
Вместо старых init-скриптов теперь используются units (systemd единицы), каждая из которых управляет отдельным сервисом или процессом.
Несмотря на это, большинство дистрибутивов сохраняют возможность перехода между классическими уровнями исполнения через команду telinit или специальные команды типа init N (хотя последнее устарело и рекомендуется избегать его использования).


Для переключения между уровнями чаще всего применяются следующие инструменты:
Традиционные команды вроде init и telinit (устаревшие, но поддерживаются для совместимости);
Инструменты нового поколения, такие как команда systemctl isolate в systemd.

Пример команды для смены уровня в системе с systemd:
sudo systemctl isolate multi-user.target # эквивалент старого уровня 3



Runlevels позволяют гибко настраивать работу системы в зависимости от потребностей пользователей и администратора.
#520_DvOp_NTWK_TP

Какие методы запросов поддерживает HTTP?

HTTP-протокол поддерживает ряд методов запросов, каждый из которых служит определенной цели взаимодействия клиента и сервера.


Основные методы HTTP:

GETиспользуется для извлечения данных с сервера.
Не должен изменять состояние ресурса на сервере.

Безопасность считается безопасным методом, поскольку не вызывает побочных эффектов.
Идемпотентностьповторные запросы возвращают одинаковый результат.
Данные передаются в виде параметров в URL (строке запроса).

POST — применяется для отправки данных на сервер с целью обработки (создания новых ресурсов, передачи форм и т.п.).
Может вызывать изменения на стороне сервера.
Не безопасен и не идемпотентен.
Передаваемые данные помещаются в тело запроса.


PUT — предназначен для обновления существующего ресурса или создания нового ресурса по указанному URI.
Если ресурс существует, обновляет его целиком; если нет — создает новый.

Идемпотентен, повторные PUT-запросы приводят к одному и тому же состоянию ресурса.

DELETE — удаляет указанный ресурс на сервере.
Считается идемпотентным, так как повторные DELETE-запросы дадут тот же эффект (или ничего не сделают, если ресурс уже удалён).

HEAD — аналогичен GET, но возвращает только заголовки ответа, без тела документа.
Удобен для проверки доступности ресурса или выяснения размера файла перед скачиванием.

OPTIONS — запрашивает список методов, поддерживаемых указанным ресурсом.
Часто применяется для кросс-доменных запросов (CORS), чтобы проверить допустимые способы взаимодействия с ресурсом.

PATCH — использует частичное обновление ресурса, позволяя клиенту отправить лишь необходимые изменения.
Предпочтительный метод, когда полное обновление ресурса с использованием PUT неэффективно или невозможно.

CONNECT — устанавливает туннель (обычно для прокси-серверов), часто используется для реализации HTTPS-туннелирования через прокси.

TRACE — возвращает сообщение запроса обратно клиенту, позволяя диагностировать проблемы связи.
Редко используется в обычной практике разработки веб-сервисов.


Дополнительная информация:
Методы POST, PUT и PATCH предназначены для внесения изменений на сервере и называются небезопасными.
Методы GET, HEAD и OPTIONS считаются безопасными, так как не вызывают изменений на сервере.
Методы GET, HEAD, PUT и DELETE являются идеmpoтентыми методами, потому что повторные вызовы этих методов приведут к одному и тому же результату.


Эти методы обеспечивают богатое взаимодействие клиентских приложений с серверами, предоставляя возможности для безопасного и эффективного обмена информацией.
#521_ADM_DvOp_NTWK_TP

Что такое VLAN?
Какие основные цели использования VLAN?


VLAN (Virtual Local Area Network) технология, позволяющая создавать логические сети внутри физической инфраструктуры Ethernet.
Она позволяет разделить одну физическую локальную сеть на несколько изолированных виртуальных сетей, даже если устройства физически находятся в одной подсети или сегментах одного физического оборудования (коммутатора).


Цели использования VLAN:
Повышение безопасностиизоляция трафика между разными подразделениями или группами пользователей снижает риск несанкционированного доступа к данным и улучшает контроль над сетевыми ресурсами.
Оптимизация производительностиразделение больших физических сетей на меньшие логические сегменты уменьшает количество широковещательных сообщений, предотвращая перегрузку сети и повышая её производительность.
Гибкость организации сетипозволяет организовать логически независимые группы пользователей вне зависимости от их физического расположения. Пользователи из разных этажей здания или кампусов могут находиться в одном виртуальном сегменте.
Упрощение управления сетьювозможность централизованного управления правами доступа и политиками безопасности для каждой виртуальной сети упрощает настройку и обслуживание сети.
Поддержка мобильных сотрудниковпользователи могут перемещаться между физическими сегментами сети, сохраняя принадлежность к своей виртуальной сети, что удобно для крупных организаций с мобильными сотрудниками.


Как реализуется VLAN?
При работе с VLAN каждому устройству назначается определенный тег (идентификатор VLAN), который добавляется к каждому пакету данных на канальном уровне (L2).
Когда пакет передается через сеть, коммутаторы считывают этот тег и направляют пакеты только в соответствующие виртуальные сети.


Основные технологии для поддержки VLAN:
IEEE 802.1Q — стандарт маркировки кадров, позволяющий передавать информацию о принадлежности пакета к конкретной VLAN.
Native VLAN — специальный случай, когда трафик проходит без добавления тегов (чаще всего используется для untagged-трафика).


Использование VLAN стало стандартной практикой в корпоративных сетях благодаря своим преимуществам в области безопасности, производительности и удобства администрирования.
#522_ADM_DvOp_NTWK_TP

Этапы работы DNS от момента, когда пользователь вводит доменное имя.

DNS распределённая иерархическая система, состоящая из множества серверов разного уровня, работающих совместно для быстрого и надежного преобразования доменов в IP-адреса.


Процесс разрешения доменного имени в IP-адрес посредством DNS включает несколько последовательных этапов:

Этапы работы DNS:

Пользователь вводит доменное имя в браузерепредположим, пользователь вводит адрес сайта example.ru.
Проверка кэша браузера и операционной системыпрежде чем отправлять запрос внешнему источнику, браузер сначала проверяет собственный кэш DNS и кэш операционной системы (локальный кеш Linux, Windows или macOS).
Если IP-адрес найден здесь, процесс заканчивается сразу.
Запрос к DNS-кэшеру провайдера (резольвер)eсли требуемый IP-адрес не обнаружен в локальном кэше, компьютер отправляет рекурсивный запрос к DNS-серверу своего интернет-провайдера (DNS-resolver).
Этот сервер отвечает за получение конечного IP-адреса, запрашивая последовательно вышестоящие DNS-серверы.
Обращение к корневому DNS-серверупровайдерский DNS-server посылает запрос на один из корневых DNS-серверов (.com, .ru и т.д.).
Корневые серверы содержат информацию о зонах верхнего уровня (Top Level Domains, TLD), например, .ru, .org, .com и передают дальнейший запрос соответствующему серверу зоны.
Обращение к серверу имен зоны (TLD-сервер)получив информацию от корневого сервера, резольвер обращается к серверу имен соответствующей зоны, например, к серверу, ответственному за зону .ru.
Сервер зоны сообщит IP-адрес авторитетного DNS-сервера конкретного домена (например, example.ru).
Получение IP-адреса от авторизованного DNS-сервераавторитетный DNS-сервер домена example.ru хранит непосредственную привязку имени домена к IP-адресу. После обращения резольвера этот сервер возвращает нужный IP-адрес.
Кэширование результатаответ возвращается провайдерскому DNS-серверу, который сохраняет полученный IP-адрес в своем кэше для последующих обращений.
Затем этот IP отправляется обратно компьютеру пользователя.
Переход к сайтуполучив IP-адрес, браузер устанавливает TCP/IP-соединение с соответствующим сервером и загружает сайт.


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


Такой алгоритм действий гарантирует надежность и эффективность интернета при обращении к миллионам доменов ежедневно.
#523_ADM_DvOp_NTWK_TP

Типы DNS записей и их значения.

Система DNS (Domain Name System)представляет собой базу данных, содержащую информацию о доменах и соответствующих им IP-адресах.
Каждое доменное имя ассоциируется с различными записями DNS, называемыми ресурсными записями (Resource Records).
Эти записи предоставляют различную информацию о домене, такую как IP-адреса, почтовые серверы, направления переадресаций и многое другое.


Распространенные типы DNS-записей и их назначения:

1. A (Address Record)
Назначение: Связывает доменное имя с IPv4-адресом.
Формат: <доменное имя> → <IPv4-адрес>
Пример: www.example.com IN A 192.0.2.1

2. AAAA (Quad-A Address Record)
Назначение: Связывает доменное имя с IPv6-адресом.
Формат: <доменное имя> → <IPv6-адрес>
Пример:
www.example.com IN AAAA 2001:DB8::1

3. CNAME (Canonical Name Record)
Назначение: Создает псевдоним (алиас) другого доменного имени. Все запросы, направленные на псевдоним, будут автоматически перенаправлены на основное доменное имя.
Формат: <псевдоним> → <основное доменное имя>
Пример: blog.example.com IN CNAME www.example.com

4. MX (Mail Exchanger Record)
Назначение: Определяет почтовые серверы, принимающие почту для указанного домена.
Формат: <доменное имя> → <почтовый сервер>
Пример:
example.com IN MX 10 mail.example.com

5. NS (Name Server Record)
Назначение: Указывает, какой DNS-сервер отвечает за доменную зону.
Формат: <доменная зона> → <сервер имен>
Пример:
example.com IN NS ns1.example.net

6. PTR (Pointer Record)
Назначение: Осуществляет обратное разрешение IP-адреса в доменное имя (reverse DNS lookup).
Формат: <IP-адрес> → <доменное имя>
Пример:
1.2.3.4.in-addr.arpa IN PTR server.example.com

7. SOA (Start of Authority Record)
Назначение: Содержит административную информацию о зоне DNS, включая контактную информацию администратора, серийный номер и таймеры повторных проверок.
Формат: <имя зоны> → <первичный мастер DNS>, <email администратора>, <серийный номер>, <тайминги>
Пример:
example.com IN SOA ns1.example.com admin.example.com (1 3600 600 86400 3600)

8. TXT (Text Record)
Назначение: Хранит произвольные текстовые данные, например, SPF-записи для подтверждения подлинности электронной почты, DKIM-подписи и другие служебные данные.
Формат: <доменное имя> → <текстовое значение>
Пример:
example.com IN TXT "v=spf1 include:_spf.google.com ~all"

9. SRV (Service Locator Record)
Назначение:
Определять местонахождение конкретных сервисов (например, SIP, LDAP, Jabber и т.д.) в пределах доменной зоны.
Формат: _service._protocol.<domain-name> → <приоритет вес port host>
Пример:
_sip._tcp.example.com IN SRV 0 5 5060 sipserver.example.com

10. CAA (Certification Authority Authorization Record)
Назначение:
Управляет полномочиями центров сертификации (CA) выдавать SSL/TLS сертификаты для определенного домена.
Формат: <доменное имя> → <флаг issue|issuewild|iodef> "<CA>" [";" options]
Пример:
example.com IN CAA 0 issue "letsencrypt.org"


Эти типы DNS-записей
обеспечивают надежное функционирование интернета путем перевода понятных человеку доменных имен в машиночитаемые IP-адреса и предоставления дополнительной информации о доменах, необходимой для правильной доставки писем, обеспечения безопасности и настройки сетевых сервисов.
#524_ADM_DvOp

Что делает команда docker prune ?

Команда docker system prune служит для очистки неиспользуемых объектов Docker, включая образы контейнеров, тома, сети и построенные кэшированные слои образов. По умолчанию эта команда удаляет следующие объекты:

Остаточные незадействованные образы контейнеров ("dangling images") — образы, которые больше не используются ни одним работающим контейнером.
Неиспользуемые тома ("volumes"), созданные ранее контейнерами, но теперь ненужные.
Удалённые несвязанные сети ("networks").
Построенный кэш сборки образа ("build cache"). Этот кэш помогает ускорить последующие операции сборки, но иногда занимает много места.

Опционально команду можно дополнить флагами, расширив её возможности удаления:

--all (-a) — удаление всех остановленных контейнеров, неиспользованных образов (не только dangling), а также всё остальное.
--force (-f) — принудительное выполнение команды без подтверждения.
--volumes (-v) — дополнительно удалить все неиспользуемые тома.

Пример полного удаления всего ненужного, включая объёмы:

docker system prune --all --volumes

Эта команда очистит систему от любых остаточных элементов Docker, освободив дополнительное пространство на диске.
#526_RUST_Vim

Плагины vim для работы c Rust.

Популярные плагины Vim для разработки на Rust, которые существенно упрощают процесс написания, тестирования и компиляции кода:

1. Rust.vim.
Описание: Официальный синтаксис и автозавершение для Rust.
Установка: Через менеджер плагинов, например Vundle, Vim-plug:
Plugin 'rust-lang/rust.vim'

Особенности: Улучшенный синтаксис, подсветка ошибок, поддержка формата Cargo.toml.


2. Vim-Racer.
Описание: Интеграция Racer для автодополнения Rust-кода.
Установка: Vundle, Vim-plug:
Plugin 'racer-rust/vim-racer'

Особенности: Быстрая автодополнение и навигация по коду, интегрирована с cargo build.

3. Ale.
Описание: Асинхронный Linter Engine для проверки кода на ошибки.
Установка: Vundle, Vim-plug:
Plugin 'dense-analysis/ale'

Особенности: Поддерживает интеграцию с clippy и rustfmt, проверка синтаксиса и стиля кода прямо в редакторе.


4. LanguageClient-vim.
Описание:
Клиент Language Server Protocol (LSP) для интеграции различных серверов анализа и автодополнения.
Установка: Vundle, Vim-plug:
Plugin 'autozygote/languageclient-vim'

Особенности: Позволяет подключаться к серверам вроде rls (Rust Language Server) для полноценного автодополнения, рефакторинга и навигации.


5. Easymotion.
Описание:
Ускорение перемещения по файлам с помощью комбинаций клавиш.
Установка: Vundle, Vim-plug:
Plugin 'easymotion/vim-easymotion'

Особенности: Полезен для быстрого перехода по большим проектам и структурам кода.


6. YouCompleteMe.
Описание: Автодополнение для множества языков программирования, включая Rust.
Установка: Vundle, Vim-plug:
Plugin 'ycm-core/YouCompleteMe'

Особенности: Мощное автодополнение, требует предварительной сборки, но обеспечивает высокую производительность.


7. Vim-cargo.
Описание: Удобства для работы с Cargo (менеджером проектов Rust).
Установка: Vundle, Vim-plug:
Plugin 'sheerun/vim-cargo'

Особенности: Команды для запуска тестов, сборки, обновления зависимостей прямо из редактора.


8. TabNine.
Описание:
Умное автодополнение на основе машинного обучения.
Установка: Vundle, Vim-plug:
Plugin 'tabnine/tabnine-vim'

Особенности: Подсказки на основе глубокого обучения, улучшает качество предложений.


Настройка минимального рабочего окружения:
Пример простого конфига Vim для комфортной работы с Rust-проектами:
set nocompatible                " Включаем режим совместимости
syntax on " Используем подсвечивание синтаксиса
filetype plugin indent on " Загружаем плагины для каждого типа файлов

call plug#begin('~/.vim/bundle')
Plug 'rust-lang/rust.vim' " Оффициальный плагин поддержки Rust
Plug 'dense-analysis/ale' " Линтер
Plug 'sheerun/vim-cargo' " Управление проектами через Cargo
Plug 'raimon49/vim-autoclose' " Автоматическое закрытие скобок и кавычек
call plug#end()

" Настройки ALE
let g:ale_fix_on_save = 1 " Исправлять стиль кода при сохранении
let g:ale_linters_explicit = 1 " Использовать конкретные линтеры
let g:ale_rust_cargo_check_command = ['cargo', '+nightly', 'check']

" Настройки RLS (если используете)
if executable('rls') || executable('cargo')
let g:LanguageClient_serverCommands = {
\ 'rust': ['rls'],
\ }
endif



Используя такие инструменты, можно значительно повысить продуктивность и удобство разработки на Rust в Vim.
#527_Vim_TLS

Как настроить Vim таким образом, чтобы при работе с различными языками использовались только определенные плагины, а какие-то плагины работали всегда и везде?

Для настройки Vim таким образом, чтобы отдельные плагины включались автоматически при открытии файлов определённых типов, а некоторые плагины загружались постоянно вне зависимости от типа файла, удобно воспользоваться механизмом автоматического запуска команд (autocmd) и менеджером пакетов, например vim-plug или встроенным пакетом системы самого Vim — packer.nvim.


Пример конфигурации с использованием менеджера vim-plug.
Предположим, мы хотим включить следующие плагины:
Всегда включены: подсветка синтаксиса (syntastic), работа с тегами (tagbar)
Включаются только при редактировании Python-файлов:
автоформатирование (autopep8), автодополнение (jedi-vim)
Включаются только при редактировании JavaScript-файлов: ESLint интеграция (vim-eslint), автодополнение для JSX/TSX (tern_for_vim)


Шаги:
Убедитесь, что у вас установлен менеджер пакетов, например vim-plug.

Для установки выполните команду внутри Vim:

:PlugInstall

Добавьте следующую конфигурацию в ваш .vimrc или аналогичный файл настроек:
" Всегда подгружаемые плагины
call plug#begin('~/.vim/plugs')

" Подсветка ошибок (работает везде)
Plug 'scrooloose/syntastic'

" Работа с Ctags (отображает структуру проекта)
Plug 'majutsushi/tagbar'

" Плагины по языку программирования

" Только для Python
au FileType python Plug 'nvie/vim-autpep8' | Plug 'davidhalter/jedi-vim'

" Только для JavaScript
au FileType javascript,jsx Plug 'vim-javascript/vim-jsx' | Plug 'mxw/vim-jsx'

" Общие команды для загрузки всех указанных плагинов
call plug#end()

Как работает эта настройка?
Сначала устанавливаются два глобальных плагина, которые будут активированы всегда: syntastic и tagbar.
Далее с помощью механизма автокоманд (FileType) указывается, что при открытии файлов Python и JavaScript подключаются дополнительные специфичные для этих языков инструменты.

Например, команда:
au FileType python Plug 'nvie/vim-autpep8' | Plug 'davidhalter/jedi-vim'

означает следующее: если тип текущего открытого файла определяется как python, тогда загрузятся плагины vim-autpep8 и jedi-vim.

Аналогично:

au FileType javascript,jsx Plug 'vim-javascript/vim-jsx' | Plug 'mxw/vim-jsx'

подключит плагины только при открытии файлов JavaScript и JSX.


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


Если вы используете другой
пакет-менеджер, процесс аналогичен: прописываете общесистемные плагины отдельно, а зависимые от языка файлы — внутри блока автозагрузки.


Такой подход помогает избежать избыточности и делает работу с редактором удобной и быстрой.
#528_C_Cpp_Vim_TLS

Набор плагинов для Vim для работы с С и С++.

Для эффективной разработки на C и C++ в редакторе Vim существует множество полезных плагинов, облегчающих работу программиста и повышающих продуктивность.


Основные категории плагинов.

Автодополнение и интеллектуальная навигация
эти плагины помогают быстрее писать код и лучше ориентироваться в проекте.

YouCompleteMeодин из лучших автодополнителей для Vim, поддерживает C/C++, JavaScript, Python и многие другие языки.
Работает быстро благодаря своему асинхронному движку.

Clangdинтегрирует LLVM/Clange-based сервер LSP для Vim, обеспечивая автодополнение, подсказки типов, переходы к определению и рефакторинг.

ALE (Asynchronous Lint Engine)проверяет синтаксис и стиль написания кода в режиме реального времени, поддерживая различные инструменты анализа кода (например, clang-tidy, cppcheck).

Vim-lsp
простое подключение к Language Server Protocol (LSP), которое позволяет получать автозавершение, проверку ошибок, подсказки и многое другое непосредственно из компилятора или инструментов статического анализа (таких как clangd).

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

Vimsynstaxулучшенная подсветка синтаксиса для C и C++, включающая поддержку комментариев, строковых литералов, регулярных выражений и различных конструкций препроцессора.


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

NERDTreeграфический файловый менеджер внутри редактора, позволяющий удобно просматривать дерево файлов и каталогов вашего проекта.

FZF.vimфильтрует файлы, строки и команды, позволяя мгновенно находить нужные элементы с помощью быстрого фильтра.

Vinegarулучшенный интерфейс для перемещения по директориям и работе с деревьями файлов прямо из Vim.

Projectile-vim
помогает управлять большими проектами — быстрое открытие файлов, быстрый доступ к задачам сборки, тестирования и деплоймента.

LeaderFбыстрый доступ к проектным элементам (файлы, буферы, команды) с использованием удобных горячих клавиш.


Отладка и тестирование.
Эти плагины упрощают процесс отладки и тестирования приложений.

Gdb.vimинтеграция с GNU Debugger (GDB).
Позволяет запускать дебаггер прямо из Vim, устанавливать точки останова, смотреть стек вызовов и значения переменных.

Cquery (или его замена bear-cmake) + LanguageClient-nvimиспользуется совместно с LSP-сервером cquery (замещён bear-cmake), позволяющим полноценно интегрироваться с IDE-подобными функциями вроде автозаполнения, определения символов и навигации по проекту.

Dbgp.vimдля удалённой отладки PHP-кода (если используете PHP вместе с C/C++).

Сpptest
поддерживает интеграцию тестов для библиотек Google Test, Boost.Test и Catch.

.
🔥1
Навигация и поддержка стандартов программирования.
Помощь в написании качественного и читаемого кода.

Surround.vim
быстро добавляет окружение вокруг текста (скобки, кавычки, фигурные скобки и т.п.).

IndentLine
отображает вертикальные линии отступов, помогающие визуально отслеживать уровни вложенности блоков кода.

Alignвыравнивает части исходного кода (например, выравнивает присвоенные значения, аргументы функций и комментарии).

Tabular
инструмент для автоматического выравнивания определённых элементов кода, типа объявлений переменных или аргументов функций.

Commentaryудобное комментирование выделенного блока кода одной командой (gcc), хорошо работает с разными языками программирования.

Ctagsгенерирует метаданные о проекте (функциях, классах, методах и т.д.) для быстрой навигации по ним.
Рекомендуется использовать в связке с Tagbar.


Форматирование и автоматическое исправление.
Улучшите качество своего кода автоматически!

ALE
проверяет код на наличие ошибок и предлагает улучшения стиля (поддерживает много утилит, включая clang-format, cppcheck и др.)

Prettier.vim
eсли важно соблюдать стандарты оформления, этот плагин интегрируется с Prettier для автоматического форматирования кода согласно заданным правилам.

autopep8, black, isortхотя эти плагины ориентированы больше на Python-код, но полезны и для проектов смешанного характера (например, если у вас используется скриптинг на Python).

Сlang-format
официальная утилита форматирования от разработчиков LLVM, которая отлично справляется с форматом кода для C/C++.


Дополнительные полезные дополнения.

Lightline.vim
минималистичный статусбар с информацией о файле, позиции курсора, наличии изменений и многом другом.

Unite.vimмощный механизм поиска, навигации и фильтрации всего: файлов, буферов, команд, истории и т.д.

Minimap.vim
мини-карта, показывающая общее представление структуры открытого файла.

Fugitive.vimполноценная интеграция Git в Vim, позволяет выполнять практически любые операции с репозиториями Git прямо из редактора.


Комбинируя перечисленные плагины, можно настроить мощную среду разработки для
C и C++ в Vim, значительно упростив жизнь и ускорив рабочий процесс.
#529_ALG_GO_PPPO

Какой способ вставки элементов в начало или конец слайса (slice — срез) наиболее оптимален в Golang?
Поэлемнтное копирование —> вставка нового значения —> копирование последующих элементов?
Или использование операции append()?



При вставке нового элемента в начало или середину среза в Go наиболее эффективным решением является использование метода копирования вручную ("поэлементное копирование"), поскольку операция append() предназначена больше для добавления новых элементов в конец среза и работает неэффективно при вставке внутрь существующего среза.


Почему лучше избегать append()?
Операция append() создает новый внутренний массив, куда сначала копируются элементы старого среза, затем добавляется новый элемент.
Это полезно именно тогда, когда новые элементы добавляются в конец, потому что здесь автоматически увеличивается длина слайса.
Однако, если вы пытаетесь добавить элемент в произвольную позицию внутри среза (например, в начало), выполнение операции append() влечет два этапа:
создание копии всего текущего среза (так как сдвиг всех последующих элементов необходим).
— вставка нового элемента перед существующими элементами.

Это значительно менее эффективно, особенно для больших срезов, так как вся работа сводится к ненужному двойному копированию памяти.


Ручное копирование эффективнее:
Лучше самому реализовать ручной перенос значений с использованием функции copy() для части массива, находящейся слева от новой позиции, и для части справа от неё.

Рассмотрим пример вставки элемента в середину:
package main

import (
"fmt"
)

func insertElement(slice []int, pos int, value int) []int {
lenSlice := len(slice);
newSlice := make([]int, lenSlice + 1);
// Копируем левую половину
copy(newSlice[:pos], slice[:pos]);
// Добавляем новый элемент
newSlice[pos] = value;
// Копируем правую половину
copy(newSlice[pos+1:], slice[pos:lenSlice]);
return newSlice;
}

func main() {
slice := []int{1, 2, 3, 4, 5}
pos := 2
value := 100
result := insertElement(slice, pos, value)
fmt.Println(result) // Выведет: [1 2 100 3 4 5]
}


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

Такой подход
гораздо быстрее, так как:
— используется прямая копия элементов.
— нет повторного выделения памяти, кроме необходимого увеличения размера массива ровно на одну ячейку.


Для эффективной вставки элемента в середину или начало среза используйте ручное копирование элементов, используя стандартную функцию copy().

Операцию append() лучше оставить для добавления элементов в конце срезов, там её производительность оптимальна.
#530_GIT_GO_TLS

Последовательность действий для создания нового проекта на Go и его размещения на Github c учетом современныйх подходов и лучших практик разработки проектов.


Создание нового проекта на Go и размещение его на GitHub включает ряд шагов, начиная от инициализации среды разработки и заканчивая публикацией исходного кода и обеспечением качественной архитектуры проекта.


Рассмотрим этапы разработки Go-проектов:


1. Подготовка окружения и создание проекта

Установка Goубедитесь, что у вас установлена последняя стабильная версия Go:
go version


Установите последнюю версию Go, следуя инструкциям на официальном сайте:
https://golang.org/doc/install.


Создание рабочего пространстваcоздаем рабочую директорию проекта:
mkdir go-project && cd go-project


Инициализируем модуль Go:
go mod init example.com/go-project


Здесь example.com/go-project уникальный путь к проекту, соответствующий стандартному пути импорта пакетов в Go.


Структура директорийиспользуйте следующую структуру файлов и директорий для проекта:
go-project/
├── cmd/
│ └── main.go # точка входа приложения
├── internal/
│ ├── config/ # конфигурационные файлы
│ ├── handler/ # обработчики HTTP-запросов
│ ├── model/ # модели данных
│ ├── repository/ # слой взаимодействия с базой данных
│ └── service/ # бизнес-логика сервиса
├── pkg/ # внешние библиотеки и общие утилиты
├── vendor/ # зависимости проекта (опционально)
├── .gitignore # файл игнорирования ненужных файлов
├── Dockerfile # Docker-файл для контейнеризации
├── Makefile # автоматизация сборки и запуска
├── README.md # описание проекта
├── go.mod # файл модуля
└── go.sum # хеш-зависимости



2. Настройка и написание начального кода.

Добавление точки входа (main.go) — cоздаем точку входа в проекте в файле cmd/main.go:
package main

import (
"fmt"
)

func main() {
fmt.Println("Hello from Go!")
}



Написание простой логикиcоздаем пример простейшего API-контроллера в пакете internal/handler.

Файл internal/handler/api.go:
package handler

import (
"net/http"
"github.com/gorilla/mux"
)

// HealthCheckHandler проверяет работоспособность сервера
func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status": "ok"}`))
}

// RegisterRoutes регистрирует маршруты
func RegisterRoutes(router *mux.Router) {
router.HandleFunc("/healthz", HealthCheckHandler).Methods("GET")
}


Запуск сервера в cmd/main.go:
package main

import (
"log"
"net/http"
"github.com/gorilla/mux"
"go-project/internal/handler"
)

func main() {
router := mux.NewRouter()
handler.RegisterRoutes(router)
log.Fatal(http.ListenAndServe(":8080", router))
}



3. Тестирование и покрытие тестов.

Напишите тесты для контроллеров и сервисов.
Пример теста в internal/handler/api_test.go:
package handler

import (
"bytes"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)

func TestHealthCheckHandler(t *testing.T) {
req, err := http.NewRequest("GET", "/healthz", nil)
if err != nil {
t.Fatal(err)
}

recorder := httptest.NewRecorder()
HealthCheckHandler(recorder, req)

body, _ := ioutil.ReadAll(recorder.Body)
expectedBody := `{"status":"ok"}`

if recorder.Code != http.StatusOK || string(body) != expectedBody {
t.Errorf("Expected response code %d and body '%s', got %d and '%s'", http.StatusOK, expectedBody, recorder.Code, string(body))
}
}



4. Автоматизация процесса сборки и тестирования.

Создайте Makefile для автоматизации процесса компиляции, тестирования и упаковки проекта:
.PHONY: build test run clean

build:
go build -o bin/app .

run:
go run ./cmd/main.go

test:
go test -v ./...

clean:
rm -rf bin/*


Теперь можно собрать приложение и запустить тесты:
make build
make test
./bin/app


.
5. Публикация проекта на GitHub.

Инициализация git-репозиторияcоздайте локальный репозиторий Git:
git init



Игнорирование файловcоздайте .gitignore файл, добавив туда стандартные исключения:
echo ".DS_Store
bin/
vendor/" > .gitignore


Или используйте готовый шаблон .gitignore: https://github.com/github/gitignore/blob/master/Go.gitignore


Добавьте и закоммитте файлы:
git add .
git commit -m "Initial project setup"



Создайте удаленный репозиторий на GitHubзалогиньтесь на GitHub и создайте новый пустой репозиторий с названием, соответствующим проекту.

Затем свяжите ваш локальный репозиторий с удаленным:
git remote add origin <url вашего репозитория на GitHub>


Отправляем наш первый коммит на сервер:
git push -u origin master



Контейнеризация и развертывание.

Создаем Dockerfile для контейнера нашего приложения:
# Dockerfile
FROM golang:alpine AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/app .
EXPOSE 8080
CMD ["./app"]


Собираем образ и запускаем контейнер:
docker build -t my-go-app .
docker run -p 8080:8080 my-go-app



Вот основные шаги для создания проекта на Go и его публикации на GitHub:
— установка Go и настройка рабочего пространства;
— использование современной организации каталогов и модулей;

— применение хорошей практики написания кода и тестирования;
— организовали процесса сборки и тестирование через
Makefile
;
— размещение проекта на GitHub и настройка конвейера доставки через
Docker.


Следование данным рекомендациям позволит поддерживать качественный и легко поддерживаемый проект.
#531_GO_TLS

Стандартный путь импорта пакета в Goопределяется правилами именования импортируемых модулей, основанными на концепции уникальности доменного имени разработчика и четкого указания местоположения пакета.
Этот путь должен однозначно определять источник происхождения пакета и обеспечивать возможность его повторного использования другими разработчиками.

Правила формирования стандартного пути импорта в Go:
Доменное имя владельца. Обычно используется полное доменное имя разработчика или организации, которое гарантирует уникальность названия пакета.
Например, если пакет разработан компанией Google, название начинается с "google.com" или аналогичного зарегистрированного домена.
Таким образом, можно видеть, откуда пришел пакет, и избегать конфликтов имен.

Поддомены или префиксы, уточняющие принадлежность проекта.
Например, если разработчик владеет сайтом example.com, путь может выглядеть как example.com/myproject или даже глубже, с указанием подпроекта: example.com/myproject/submodule.

Отсутствие верхнего уровня папок, относящихся к операционной системе или среде разработки.
Традиционно пакеты Go хранятся вне каталога GOPATH, и их расположение фиксируется именно на уровне сайта разработчика.

Пример правильного пути импорта:
Неправильно:
/home/user/projects/go_project/src/my_package


Правильно:
example.com/go-project/pkg/my_package


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


Как работает механизм импорта?
Когда вы используете команду go get, система автоматически загружает указанный вами пакет с указанного домена (если этот домен доступен и публикует код, например, на GitHub или другом хостинге).
Использование стандартных путей помогает избежать коллизий и обеспечивает ясность при работе с внешними библиотеками.

Формат полного пути:
<DOMAIN>/<PROJECT_NAME>[/SUB_PROJECT][/PACKAGE_NAME]


Например:
Пакет находится здесь: https://github.com/google/go-prometheus
Импорт осуществляется следующим образом:
import "github.com/google/go-prometheus"


Этот путь позволяет другим пользователям точно понимать происхождение пакета и его уникальную идентификацию.


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