Процесс компиляции GNU от исходного кода до исполняемого файла (Описание к предыдущему посту)
Процесс начинается с исходного кода в текстовых файлах (например, программы на языке C) и запускается с препроцессора, который часто называют cpp.
Предположим, исходный код находится в файле prog.c.
Препроцессор расширяет макросы, подключает заголовочные файлы и обрабатывает директивы, преобразуя исходный код в очищенную версию, которая по-прежнему остаётся в текстовом формате. Например, после обработки препроцессором cpp файла prog.c может получиться файл prog.i.
Препроцессор важен для подготовки кода путём раннего разрешения зависимостей, чтобы все определения были на месте до фактической компиляции.
Далее собственно компилятор (например, cc1 или gcc) на основном этапе берёт предварительно обработанный текст и генерирует ассемблерный код.
На этом этапе высокоуровневые инструкции преобразуются в низкоуровневый ассемблер, часто с такими оптимизациями, как преобразование кода. Вы можете увидеть команду gcc -S -m32 prog.c для вывода prog.s в текстовом формате.
Ассемблер остаётся читаемым для человека, но ближе к машинному языку, что позволяет преодолеть разрыв между языками программирования и особенностями аппаратного обеспечения.
Ассемблер (обозначается как as) преобразует этот ассемблерный текст в перемещаемые объектные файлы в двоичном формате.
Эти файлы .o содержат машинный код, но с заполнителями для адресов, отмеченными в записях перемещения, таких как разделы .rel.data или .text. Таблицы символов (.symtab) отслеживают переменные и функции.
Выполнение команды gcc -c prog.c компилирует без компоновки, создавая файл prog.o, готовый к объединению с другими файлами.
Компоновка выполняется с помощью ld, который разрешает символы и перемещает код, подключая библиотечные файлы и другие объектные модули.
Он создаёт исполняемый двоичный файл, например prog из gcc -o prog prog.c, где всем ссылкам присваиваются фиксированные адреса. На этом этапе выполняется разрешение символов, чтобы вызовы внешних функций работали корректно.
Наконец, загрузчик помещает этот исполняемый файл в память как работающий процесс, сопоставляя разделы и настраивая выполнение.
Процесс начинается с исходного кода в текстовых файлах (например, программы на языке C) и запускается с препроцессора, который часто называют cpp.
Предположим, исходный код находится в файле prog.c.
Препроцессор расширяет макросы, подключает заголовочные файлы и обрабатывает директивы, преобразуя исходный код в очищенную версию, которая по-прежнему остаётся в текстовом формате. Например, после обработки препроцессором cpp файла prog.c может получиться файл prog.i.
Препроцессор важен для подготовки кода путём раннего разрешения зависимостей, чтобы все определения были на месте до фактической компиляции.
Далее собственно компилятор (например, cc1 или gcc) на основном этапе берёт предварительно обработанный текст и генерирует ассемблерный код.
На этом этапе высокоуровневые инструкции преобразуются в низкоуровневый ассемблер, часто с такими оптимизациями, как преобразование кода. Вы можете увидеть команду gcc -S -m32 prog.c для вывода prog.s в текстовом формате.
Ассемблер остаётся читаемым для человека, но ближе к машинному языку, что позволяет преодолеть разрыв между языками программирования и особенностями аппаратного обеспечения.
Ассемблер (обозначается как as) преобразует этот ассемблерный текст в перемещаемые объектные файлы в двоичном формате.
Эти файлы .o содержат машинный код, но с заполнителями для адресов, отмеченными в записях перемещения, таких как разделы .rel.data или .text. Таблицы символов (.symtab) отслеживают переменные и функции.
Выполнение команды gcc -c prog.c компилирует без компоновки, создавая файл prog.o, готовый к объединению с другими файлами.
Компоновка выполняется с помощью ld, который разрешает символы и перемещает код, подключая библиотечные файлы и другие объектные модули.
Он создаёт исполняемый двоичный файл, например prog из gcc -o prog prog.c, где всем ссылкам присваиваются фиксированные адреса. На этом этапе выполняется разрешение символов, чтобы вызовы внешних функций работали корректно.
Наконец, загрузчик помещает этот исполняемый файл в память как работающий процесс, сопоставляя разделы и настраивая выполнение.
Telegram
METANIT.COM
Процесс компиляции GNU от исходного кода до исполняемого файла
Описание - https://news.1rj.ru/str/devnull22/1930
Описание - https://news.1rj.ru/str/devnull22/1930
👍13❤4🔥1
Распространенне паттерны программирования: (описание к предыдущему посту)
1. Two-Pointer Technique (Техника двух указателей): Используется для работы с массивами или строками, где два указателя (Pointer 1 и Pointer 2) движутся по структуре данных для решения задач, таких как поиск пар или подмассивов.
2. HashMaps: Это структура данных, которая хранит пары ключ-значение. Она использует хэш-функцию для быстрого доступа к данным.
3. Linked Lists (Связанные списки): Линейная структура данных, где каждый элемент (узел) содержит данные и ссылку на следующий элемент.
4. Fast and Slow Pointers (Быстрые и медленные указатели): Используются для обнаружения циклов в связанных списках или других структурах данных.
5. Sliding Window Technique (Техника скользящего окна): Применяется для обработки массивов или строк, где окно определенного размера перемещается по данным для выполнения операций.
6. Binary Search (Двоичный поиск): Эффективный алгоритм поиска элемента в отсортированном массиве.
7. Stacks (Стеки): Структура данных, работающая по принципу "последним пришел — первым вышел" (LIFO).
8. Heaps (Кучи): Дерево, где каждый узел больше (или меньше) своих потомков, используется для реализации приоритетов.
9. Prefix Sum (Префиксные суммы): Метод вычисления суммы элементов массива до определенной позиции.
10. Trees (Деревья): Иерархическая структура данных, где каждый узел может иметь несколько потомков.
11. Graphs (Графы): Набор узлов и ребер, соединяющих их, используется для моделирования сложных связей.
12. Backtracking (Обратное отслеживание): Алгоритм для поиска решений путем проб и ошибок, отката и повторного поиска.
13. Dynamic Programming (Динамическое программирование): Метод решения задач путем разбиения их на подзадачи и сохранения результатов для повторного использования.
14. Greedy Algorithm (Жадный алгоритм): Принимает локально оптимальные решения на каждом шаге, надеясь на глобальную оптимальность.
15. Intervals (Интервалы): Используются для работы с диапазонами значений, например, в задачах планирования.
1. Two-Pointer Technique (Техника двух указателей): Используется для работы с массивами или строками, где два указателя (Pointer 1 и Pointer 2) движутся по структуре данных для решения задач, таких как поиск пар или подмассивов.
2. HashMaps: Это структура данных, которая хранит пары ключ-значение. Она использует хэш-функцию для быстрого доступа к данным.
3. Linked Lists (Связанные списки): Линейная структура данных, где каждый элемент (узел) содержит данные и ссылку на следующий элемент.
4. Fast and Slow Pointers (Быстрые и медленные указатели): Используются для обнаружения циклов в связанных списках или других структурах данных.
5. Sliding Window Technique (Техника скользящего окна): Применяется для обработки массивов или строк, где окно определенного размера перемещается по данным для выполнения операций.
6. Binary Search (Двоичный поиск): Эффективный алгоритм поиска элемента в отсортированном массиве.
7. Stacks (Стеки): Структура данных, работающая по принципу "последним пришел — первым вышел" (LIFO).
8. Heaps (Кучи): Дерево, где каждый узел больше (или меньше) своих потомков, используется для реализации приоритетов.
9. Prefix Sum (Префиксные суммы): Метод вычисления суммы элементов массива до определенной позиции.
10. Trees (Деревья): Иерархическая структура данных, где каждый узел может иметь несколько потомков.
11. Graphs (Графы): Набор узлов и ребер, соединяющих их, используется для моделирования сложных связей.
12. Backtracking (Обратное отслеживание): Алгоритм для поиска решений путем проб и ошибок, отката и повторного поиска.
13. Dynamic Programming (Динамическое программирование): Метод решения задач путем разбиения их на подзадачи и сохранения результатов для повторного использования.
14. Greedy Algorithm (Жадный алгоритм): Принимает локально оптимальные решения на каждом шаге, надеясь на глобальную оптимальность.
15. Intervals (Интервалы): Используются для работы с диапазонами значений, например, в задачах планирования.
Telegram
METANIT.COM
Распространенне паттерны программирования
(описание)
(описание)
👍11🐳2🔥1🥰1
Роскомнадзор заблокировал в РФ сервис Speedtest из-за угрозы безопасности российского сегмента сети Интернет
Вероятно, что под запрет попадут и остальные иностранные сервисы для замера скорости доступа в интернет, а операторам будет указано обязательно использовать российские программные продукты для измерения скорости передачи данных в своих сетях, например сервис «Линкметр», сервис TelecomDaily «Мегабитус» или QMS от «Ростелекома».
https://www.interfax.ru/digital/1038766
Вероятно, что под запрет попадут и остальные иностранные сервисы для замера скорости доступа в интернет, а операторам будет указано обязательно использовать российские программные продукты для измерения скорости передачи данных в своих сетях, например сервис «Линкметр», сервис TelecomDaily «Мегабитус» или QMS от «Ростелекома».
https://www.interfax.ru/digital/1038766
Интерфакс
Роскомнадзор заблокировал в РФ сервис по замеру скорости интернета Speedtest
Роскомнадзор (РКН) заблокировал в РФ сервис по замеру скорости и качества интернет-соединения Speedtest от компании Ookla в связи с выявленными угрозами безопасности Рунету, сообщили "Интерфаксу" в пресс-службе ведомства."Доступ к сервису Speedtest ограничен…
🤡59😭9🖕6👍3🤣3🤔2❤1🤯1🥱1
Команда Stack Overflow опубликовала результаты ежегодного опроса разработчиков. В 2025 году на вопросы отвечали более 49 тыс. технических специалистов из 177 стран. В этой статье собрал интересные цифры из результатов опроса. Некоторые результаты:
Десятка популярных языков программирования в 2025 году: JavaScript (66%), HTML/CSS (61%), SQL (58%), Python (57%), Bash/Shell (48%), TypeScript (43%), Java (29%), C# (27%), С++ (23%) и PowerShell (23%).
Популярные СУБД: PostgreSQL (55%), MySQL (40%), SQLite (37%), Microsoft SQL Server (30%) и Redis (28%).
Популярные веб-фреймворки и технологии: Node.js (48%), React (44%), jQuery (23%), Next.js (20%) и ASP.NET Core (19%).
IDE и редакторы кода: VS Code (75%), Visual Studio (29%), Notepad++ (27%), IntelliJ IDEA (27%), Vim (24%), Cursor (17%), PyCharm (15%) и Android Studio (15%).
Популярные ОС для работы: Windows (49%), macOS (32%), Ubuntu (27%).
Ознакомиться с полным отчетом можно на оф сайте по ссылке https://survey.stackoverflow.co/2025/
Десятка популярных языков программирования в 2025 году: JavaScript (66%), HTML/CSS (61%), SQL (58%), Python (57%), Bash/Shell (48%), TypeScript (43%), Java (29%), C# (27%), С++ (23%) и PowerShell (23%).
Популярные СУБД: PostgreSQL (55%), MySQL (40%), SQLite (37%), Microsoft SQL Server (30%) и Redis (28%).
Популярные веб-фреймворки и технологии: Node.js (48%), React (44%), jQuery (23%), Next.js (20%) и ASP.NET Core (19%).
IDE и редакторы кода: VS Code (75%), Visual Studio (29%), Notepad++ (27%), IntelliJ IDEA (27%), Vim (24%), Cursor (17%), PyCharm (15%) и Android Studio (15%).
Популярные ОС для работы: Windows (49%), macOS (32%), Ubuntu (27%).
Ознакомиться с полным отчетом можно на оф сайте по ссылке https://survey.stackoverflow.co/2025/
🔥20👍5🏆2🤷♂1
4 распространенных приема на Python для повседневого использования #python
🤮12👍5👏1
Основные стратегии согласованности кэша:
1. Истечение срока действия (Expiration)
Сервер сообщает клиентам, как долго кэшированный ресурс остаётся действительным (например, 10 минут).
Клиенты используют кэшированную копию до истечения срока действия — без обращения к серверу.
Обычно используется для статического контента (изображений, CSS и т. д.) или предсказуемых API.
✅ Быстро: нет сетевого запроса при актуальности данных
❌ Риск устаревания: данные могут измениться до истечения срока
Лучше всего подходит, когда обновления происходят нечасто, а задержка имеет значение
2. Проверка (Validation)
Клиенты используют заголовки ETag или Last-Modified, чтобы спросить: «Изменилось ли это с тех пор, как я видел это в последний раз?»
Сервер возвращает 304 Not Modified, если ничего не изменилось, что экономит пропускную способность.
Используется в API, где данные меняются, но вы всё равно хотите избежать полной загрузки.
✅ Актуальность: всегда синхронизируется с источником
✅ Эффективность: возвращает заголовки только если ничего не изменилось
❌ Медленнее, чем попадание в кэш: требует обращения к серверу
Лучше всего подходит, когда согласованность критична, но вы всё равно хотите использовать кэширование
3. Аннулирование (Invalidation)
Когда ресурс изменяется, система пытается уведомить или очистить все кэшированные копии.
Это может быть вызвано POST, PUT, DELETE или пользовательскими сигналами.
Теоретически это гарантирует, что потребители не будут работать со старыми данными.
✅ Наивысшая согласованность
❌ Сложность масштабирования: сервер должен отслеживать, у кого есть ресурс
❌ Недружелюбно к веб: HTTP не имеет состояния; аннулирование вне пути ненадёжно
Лучше всего подходит для: внутренних систем, приложений реального времени или установок на основе WebSocket
Также можно применять гибридные стратегии. Например, истечение срока действия + проверка, что позволит найти баланс между производительностью и корректностью в масштабе.
1. Истечение срока действия (Expiration)
Сервер сообщает клиентам, как долго кэшированный ресурс остаётся действительным (например, 10 минут).
Клиенты используют кэшированную копию до истечения срока действия — без обращения к серверу.
Обычно используется для статического контента (изображений, CSS и т. д.) или предсказуемых API.
✅ Быстро: нет сетевого запроса при актуальности данных
❌ Риск устаревания: данные могут измениться до истечения срока
Лучше всего подходит, когда обновления происходят нечасто, а задержка имеет значение
2. Проверка (Validation)
Клиенты используют заголовки ETag или Last-Modified, чтобы спросить: «Изменилось ли это с тех пор, как я видел это в последний раз?»
Сервер возвращает 304 Not Modified, если ничего не изменилось, что экономит пропускную способность.
Используется в API, где данные меняются, но вы всё равно хотите избежать полной загрузки.
✅ Актуальность: всегда синхронизируется с источником
✅ Эффективность: возвращает заголовки только если ничего не изменилось
❌ Медленнее, чем попадание в кэш: требует обращения к серверу
Лучше всего подходит, когда согласованность критична, но вы всё равно хотите использовать кэширование
3. Аннулирование (Invalidation)
Когда ресурс изменяется, система пытается уведомить или очистить все кэшированные копии.
Это может быть вызвано POST, PUT, DELETE или пользовательскими сигналами.
Теоретически это гарантирует, что потребители не будут работать со старыми данными.
✅ Наивысшая согласованность
❌ Сложность масштабирования: сервер должен отслеживать, у кого есть ресурс
❌ Недружелюбно к веб: HTTP не имеет состояния; аннулирование вне пути ненадёжно
Лучше всего подходит для: внутренних систем, приложений реального времени или установок на основе WebSocket
Также можно применять гибридные стратегии. Например, истечение срока действия + проверка, что позволит найти баланс между производительностью и корректностью в масштабе.
👍9❤4👏2
В руководство по языку C++ добавлена статья про Указатели на поля и методы классов/структур
https://metanit.com/cpp/tutorial/5.29.php
#cpp #cplusplus #c++
https://metanit.com/cpp/tutorial/5.29.php
#cpp #cplusplus #c++
👍16👏9🔥4❤1🌭1
Как работают списки контроля доступом (ACL) в Linux #linux
1. ACL как расширение стандартных разрешений:
- ACL позволяет добавлять разрешения для конкретных пользователей и групп, что расширяет стандартные разрешения Linux
- Пример: создание директории с помощью команды
2. Добавление ACL-разрешений:
- С помощью команды
- ACL включает разрешения для пользователей, групп и других, а также «маску», которая определяет верхний предел разрешений
3. Роль «маски»:
- «Маска» действует как верхний предел, гарантируя, что стандартные разрешения остаются в силе
- Пример: удаление групповых разрешений с помощью
4. Использование команды setfacl:
- Команда
- Пример: добавление разрешения для пользователя с помощью
1. ACL как расширение стандартных разрешений:
- ACL позволяет добавлять разрешения для конкретных пользователей и групп, что расширяет стандартные разрешения Linux
- Пример: создание директории с помощью команды
mkdir dir и просмотр стандартных разрешений с помощью ls -ld dir2. Добавление ACL-разрешений:
- С помощью команды
getfacl dir можно просмотреть ACL-разрешения- ACL включает разрешения для пользователей, групп и других, а также «маску», которая определяет верхний предел разрешений
3. Роль «маски»:
- «Маска» действует как верхний предел, гарантируя, что стандартные разрешения остаются в силе
- Пример: удаление групповых разрешений с помощью
chmod g-r dir и проверка изменений с помощью getfacl dir4. Использование команды setfacl:
- Команда
setfacl позволяет добавлять или изменять ACL-разрешения- Пример: добавление разрешения для пользователя с помощью
setfacl -m u:jimy:r file❤8🔥4👏1
Основные компоненты Docker и взаимодействие между ними
Docker Client — это интерфейс, через который пользователь взаимодействует с Docker. Команды, такие как
Docker Host — это операционная система, на которой установлен Docker. Внутри Docker Host находятся:
- Containers — запущенные приложения, которые изолированы друг от друга.
- Images — неизменяемые шаблоны, из которых создаются контейнеры.
Docker Registry — это хранилище образов, где они могут быть загружены или загружены. На изображении показаны примеры репозиториев, таких как Ubuntu и NGINX.
Daemon — это служба, которая управляет контейнерами, образами и сетями. Она обрабатывает команды, отправленные через Docker Client.
Docker Client — это интерфейс, через который пользователь взаимодействует с Docker. Команды, такие как
docker build, docker pull и docker run, отправляются через клиент.Docker Host — это операционная система, на которой установлен Docker. Внутри Docker Host находятся:
- Containers — запущенные приложения, которые изолированы друг от друга.
- Images — неизменяемые шаблоны, из которых создаются контейнеры.
Docker Registry — это хранилище образов, где они могут быть загружены или загружены. На изображении показаны примеры репозиториев, таких как Ubuntu и NGINX.
Daemon — это служба, которая управляет контейнерами, образами и сетями. Она обрабатывает команды, отправленные через Docker Client.
👍5❤3🔥3😁3