Physics.Math.Code
151K subscribers
5.23K photos
2.21K videos
5.82K files
4.56K links
VK: vk.com/physics_math
Чат инженеров: @math_code
Учебные фильмы: @maths_lib
Репетитор IT mentor: @mentor_it
YouTube: youtube.com/c/PhysicsMathCode

Обратная связь: @physicist_i
Download Telegram
📘 The Elements of Computing Systems.zip
26.1 MB
📘 The Elements of Computing Systems: Building a Modern Computer from First Principles [2005 + 2021] Noam Nisan and Shimon Schocken

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

Достоинства:
Хорошая структурированность;
Оригинальный авторский подход.

☕️ Для тех, кто захочет задонать на кофе:
ВТБ: +79616572047 (СБП) ЮMoney: 410012169999048

#программирование #низкоуровневое_программирование #архитектура #computer_science #assembler #cpp #C

💡 Physics.Math.Code // @physics_lib
138👍27🔥9👨‍💻2🤩1🗿1
Media is too big
VIEW IN TELEGRAM
🖥 Визитка программиста 👨🏻‍💻 Если нет такой визитки, то не программист.

Видеоэкран с трёхмерной мышью из фототранзистора и двухцветных китайских матриц под управлением микроконтроллера ATmega-644 на собственной многозадачной операционной системе. Сделано на предельно дешёвой элементной базе, вся схема разведена в двух слоях.

Многооконный интерфейс с предзагруженными демо-приложениями: скрин-сейвер, графическая рисовалка, видеролики с альфа-каналом, интерактивное моделирование в реальном времени пламени на основе температурной модели горения и воды методом клеточного автомата.
Сайт автора: http://velect.ru/
Статья о реализованной в проекте многозадачности: http://www.velect.ru/articles.html

#техника #конструктор #ARM #ATmega644 #программирование #механика #разработка #микроконтроллеры

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍119🔥6418🤯15🗿134🙈3😱2🤩2😍2🌚2
Media is too big
VIEW IN TELEGRAM
⚙️ Тест 9 типов подвесок [ЛегоТехникс]

Из конструктора LEGO Technic можно собирать механические подвески — узлы, которые входят в состав моделей автомобилей, мотоциклов и других транспортных средств. Некоторые наборы LEGO Technic, в которых есть подвески:
▪️MOC-159983 — Axle with Steering, Drive, Suspension for 1:10 wheels (2023) — набор с подвеской для колёс 1:10.
▪️MOC-152716 — Simple Front Suspension (2023) — набор с простой передней подвеской.
▪️MOC-132045 — Front Race Car Suspension (2022) — набор с подвеской для передней оси гоночного автомобиля.
▪️MOC-128195 — Torsen differential mounted on a double wishbone suspension (2022) — набор с дифференциалом Торсена, установленным на подвеску с двойными поперечными рычагами.

🖥 Конструирование подводной лодки на радиоуправлении из LEGO

⚙️ Редуктор из LEGO с огромным передаточным числом

⚙️ Моделирование решения задачи передвижения автомобилей по песчаному грунту с помощью конструктора LEGO

⛔️ 7 препятствий и 5 LEGO-роботов, которые умеют шагать

⚙️ LEGO® Technic Строительство мостов: Задача на 100 кг!

🎻 Когда Lego играет на гитаре лучше, чем ты...

⚙️ Lego MindStorm

👾 Что будет, если надолго оставить инженера с конструктором Lego

#техника #конструктор #ARM #программирование #механика #разработка #микроконтроллеры

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4717🔥10❤‍🔥7😍2🤩1
👨🏻‍💻 В нашем дружественном IT-канале 🔵 Эпсилон была опубликована интересная задачка по программированию. В этом посте разберем её подробно.

👩‍💻 Задача для наших подписчиков на понимание наследования в Python: Задача: Что выведет следующий код?
class A:
def process(self):
return 'A'

class B(A):
def process(self):
return 'B'

class C(A, B):
pass

obj = C()
print(obj.process())


📜 Варианты ответов:
⚡️ — 1. А
❤️ — 2. B
👍🏻 — 3. Будет вызвано исключение TypeError
👾 — 4. С

Правильный ответ: 3. Будет вызвано исключение TypeError. Но почему так сработает?

Пояснение: Код не сможет быть даже исполнен из-за ошибки в определении класса C. При создании класса C Python пытается построить порядок разрешения методов (MRO). Класс C наследуется от A и B, при этом класс B сам является наследником A.
Это создаёт противоречивую иерархию, которую невозможно выстроить линейно и логично. С точки зрения MRO, класс A не может находиться в иерархии как до класса B (так как B наследуется от A), так и после него (так как C наследует от A после B). Это противоречие приводит к ошибке. Если вы запустите этот код, интерпретатор выдаст исключение еще на этапе создания класса C:
TypeError: Cannot create a consistent method resolution order (MRO) for bases A, B

Вывод: Задача проверяет знание не только того, как вызываются методы, но и того, как Python внутренне строит иерархии классов и не позволяет создавать некорректные наследования.

✍🏻 Напишите в комментариях, вы смогли бы решить такую задачу без подсказки? Какой первый ответ вам пришел в голову? #python #программирование #разработка #архитектура

📙 Как устроен Python. Гид для разработчиков, программистов и интересующихся [2019] Харрисон

📗 Python. Исчерпывающее руководство [2023] Бизли Д.

📕 Мощный Python: Шаблоны и стратегии работы с современным Python [2025] Максвелл Аарон

📒 Python для хакеров [2023] Ли Воган

📙 Сверхбыстрый Python [2023] Тиаго Антао

📒 Основы искусственного интеллекта в примерах на Python. 2-е изд. [2023] Анатолий Постолит

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5536🔥113🌚2👨‍💻2❤‍🔥1😢1👾1
🖥 Как лучше собирать оперативную память, если вам необходим какой-то фиксированный объем RAM, например 32 Гб ?

Очевидно, что есть два способа, если исключаем одноканал: Способ 1 (4x8 ГБ) vs Способ 2 (2x16 ГБ). Однозначно лучше и эффективнее: Способ 2 — 2 планки по 16 ГБ. Вот почему это так, особенно для современных платформ (AMD AM5 и Intel LGA 1700/1851):

▪️ 1. Меньшая нагрузка на контроллер памяти (IMC). Контроллеру памяти внутри процессора значительно проще работать с двумя планками, чем с четырьмя. Это повышает стабильность системы, особенно при работе на высоких частотах с низкими таймингами.

▪️ 2. Более высокий шанс запуска на заявленной высокой частоте. Память DDR5 особенно чувствительна к количеству модулей. Сборка из 2 планок с большой вероятностью заработает на своей штатной частоте (например, 6000 МГц) с включенным EXPO/XMP. Сборка из 4 планок почти всегда потребует ручного понижения частоты (например, до 5200-5600 МГц) или увеличения таймингов для стабильной работы.
⚠️ Потеря в производительности от более низкой частоты часто перевешивает гипотетический выигрыш от четырёхканального доступа.

▪️ 3. Возможность будущего апгрейда. У вас останутся два свободных слота на материнской плате. Если вам вдруг позарез понадобится 64 ГБ (для монтажа, работы с AI и т.д.), вы просто докупите еще два модуля по 16 ГБ. В варианте с 4x8 ГБ апгрейд возможен только полной заменой всех планок на 4 новых.

▪️ 4. Совместимость и стабильность. Комплекты из двух планок протестированы производителем и гарантированно работают вместе. Сборка из четырёх планок — это всегда лотерея, даже если вы покупаете два одинаковых комплекта по 2x8 ГБ.

Краткий итог: Для 99% пользователей, особенно геймеров, конфигурация 2 модуля по 16 ГБ является золотым стандартом и оптимальным выбором.

Нужно ли 64 ГБ для игрового компьютера? На данный момент (2025 год) для чисто игрового компьютера 64 ГБ — это избыточно. И вот почему:

▪️ Подавляющее большинство игр комфортно себя чувствуют в рамках 16-32 ГБ оперативной памяти. Даже такие современные и требовательные тайтлы, как Cyberpunk 2077 с патчейми, Alan Wake 2, Star Citizen, могут потреблять до 20-24 ГБ ОЗУ, но это включает в себя и саму ОС, и фоновые приложения.

▪️ 32 ГБ — это идеальный и достаточный объем на ближайшие 2-3 года для любых игр с запасом. Вы полностью исключите любые подтормаживания, связанные с нехваткой ОЗУ, и сможете держать открытым браузер, дискорд и другие приложения во время игры.

🖥 Когда 64 ГБ оправдано или необходимо?

▫️1. Параллельная работа с "тяжелыми" приложениями: Если вы одновременно с игрой занимается стримингом (через OBS Studio), монтажом видео, рендерингом или работаете с виртуальными машинами.
▫️2. Очень специфичные игры и моды: Некоторые симуляторы (например, Microsoft Flight Simulator 2024 с огромным количеством модов на высоких настройках) или моды для игр вроде Cities: Skylines II могут "съедать" гигантские объемы памяти.
▫️3. Работа с ИИ (AI): Локальное использование нейросетей (генерация изображений, работа с LLM-моделями) требует огромных объемов ОЗУ.
▫️4. Профессиональные задачи: Видеомонтаж в 4K/8K, работа с большими базами данных, 3D-моделирование сложных сцен.

Останавливайтесь на объеме 32 ГБ. Этого более чем достаточно для игр и многозадачности. Вкладывайте сэкономленный бюджет (от не покупки 64 ГБ) в более важные компоненты: например, в более мощную видеокарту или более быстрый накопитель. Это даст гораздо более заметный прирост производительности в играх. Если в будущем вы поймете, что 64 ГБ вам реально нужны, вы всегда сможете докупить второй идентичный комплект из 2x16 ГБ и получить в сумме 64 ГБ. Но будьте готовы к тому, что для стабильной работы системе, возможно, придется сбросить частоту памяти. #hardware #железо #техника #программирование #разработка #development #computer_science

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6332👍24❤‍🔥6💯3🗿3🤔21👨‍💻1
📜 Математика количества счастливых билетов

Давайте сегодня подумаем, а как посчитать или хотя бы оценить количество счастливых билетов при 6-значном номере? Можно ли решить такую задачу аналитически?

Давайте для интереса определим верхнюю границу количества таких билетов? Их явно меньше миллиона, верно? А может есть ещё какое-то число?

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

👨🏻‍💻 Задачка про счастливый билет : решаем на Python

📜 Математика количества счастливых билетов

#задачи #разбор_задач #программирование #информатика #олимпиады

💡 Репетитор IT mentor // @mentor_it
👍2615🔥5🗿2🤔1🤯1😱1
This media is not supported in your browser
VIEW IN TELEGRAM
⚡️ С чего начать моделирование электрических полей?

Задумывались ли вы, как «увидеть» невидимое? Электрическое поле окружает нас повсюду, от розетки до экрана смартфона. Давайте разберемся, как смоделировать его для точечных зарядов и сложных поверхностей и получить эти завораживающие картинки силовых линий и эквипотенциалей.

1. Фундамент: Главные Уравнения
▪️ Закон Кулона для точечного заряда: F = k * (q₁ * q₂) / r² . Но для поля удобнее работать с напряженностью E = F / q.
▪️ Принцип суперпозиции: Поле системы зарядов — это просто векторная сумма полей от каждого заряда в отдельности. Это наше главное оружие в моделировании.

2. Силовые Линии и Эквипотенциали
Поле можно описывать по-разному, и это ключ к красивой визуализации.
▪️Силовые линии (Графическое отображение напряженности E):
— Воображаемые линии, касательные к которым в каждой точке совпадают с вектором E.
— Свойства: Начинаются на «+» зарядах, заканчиваются на «-» или уходят в бесконечность. Никогда не пересекаются!
— Густота линий пропорциональна величине напряженности.
▪️Эквипотенциальные поверхности (Графическое отображение потенциала φ):
— Что это? Поверхности, где потенциал постоянен (φ = const).
— Свойства: Всегда перпендикулярны силовым линиям. Работа по перемещению заряда вдоль такой поверхности равна нулю.

3. Как Строить Уравнения?
Для точечного заряда q в точке (x₀, y₀):
— Потенциал: φ(x, y) = k * q / sqrt( (x - x₀)² + (y - y₀)² )
— Вектор напряженности E: Eₓ = -∂φ/∂x, Eᵧ = -∂φ/∂y (это просто частные производные, градиент со знаком минус).
А как получить уравнение силовой линии? Это уже сложнее. Силовая линия — это кривая, которая в каждой точке направлена вдоль E. Математически это решается через дифференциальное уравнение: dx / Eₓ(x, y) = dy / Eᵧ(x, y). Решая его (часто численно!), мы получаем траектории для наших визуализаций.

4. Инструменты для Моделирования и Визуализации
▪️Python — король научной визуализации: Библиотеки: matplotlib, numpy, scipy.
▪️Как: Задаете сетку точек (x, y), для каждой считаете Eₓ и Eᵧ (суммируя вклады от всех зарядов). Затем:
— Для силовых линий: используйте matplotlib.streamplot
— Для эквипотенциалей: matplotlib.contour или contourf для потенциала φ.

🖥 Простой пример кода для двух зарядов:
import numpy as np
import matplotlib.pyplot as plt

# Создаем сетку
x = np.linspace(-2, 2, 100)
y = np.linspace(-2, 2, 100)
X, Y = np.meshgrid(x, y)

# Задаем заряды (q, x, y)
charges = [(1, -0.5, 0), (-1, 0.5, 0)]

# Вычисляем полные Eₓ и Eᵧ на сетке
Ex = np.zeros(X.shape)
Ey = np.zeros(Y.shape)
k = 9e9
for q, xq, yq in charges:
R = np.sqrt((X - xq)**2 + (Y - yq)**2)
Ex += k * q * (X - xq) / R**3
Ey += k * q * (Y - yq) / R**3

# Рисуем силовые линии
plt.streamplot(X, Y, Ex, Ey, color='blue', linewidth=1, density=2)
plt.show()

Готовые симуляторы:
— PhET Interactive Simulations (отлично для начального понимания).
— Falstad's E&M Simulator (очень наглядно).
— Comsol Multiphysics, Ansys — для серьезного моделирования сложных поверхностей.

🔴 А что с Крупными Заряженными Поверхностями? Здесь принцип суперпозиции остается, но суммирование становится интегрированием. Каждую поверхность разбиваете на маленькие точечные заряды dq и интегрируете их вклад в поле. На практике для сложных форм это почти всегда делается численными методами (например, методом конечных элементов), которые и используют пакеты вроде Comsol. Начните с Python и пары точечных зарядов. Поймите связь между φ и E, научитесь строить streamplot и contour. #электричество #физика #моделирование #визуализация #python #наука #образование #электрическоеполе #программирование

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
686👍49🔥20🤔43🤩2🗿1
🖥 Различия в создании строк на Java

Есть два самых популярных способа создания строк:
1 — String s1 = new String("Hello");
2 — String s2 = "Hello";
Разберем отличия.

▪️ 1. Место в памяти (Самое главное отличие) — Это отличие является корнем всех остальных различий.

🔸String s1 = new String("Hello"); (Оператор new)
Создает новый объект в Куче (Heap), независимо от того, какая строка там уже существует.
Каждый вызов new String("Hello") гарантированно создает новый, уникальный объект в памяти.

🔸String s2 = "Hello"; (Строковый литерал)
Строка создается и помещается в специальную область памяти — String Pool (Пул строк), который находится внутри кучи.
Механизм String Pool: Перед созданием новой строки JVM проверяет, нет ли уже строки с таким же значением в пуле. Если есть — переменной просто присваивается ссылка на существующий объект. Если нет — тогда в пуле создается новый объект.

Наглядная аналогия:
new String("Hello") — покупка нового, уникального экземпляра книги, даже если она уже есть в библиотеке.
"Hello" — взятие книги из библиотеки. Если книга есть — вы получаете именно её. Если нет — библиотека сначала покупает новую, а вы её берете.

▪️ 2. Поведение при сравнении (==). Оператор == сравнивает ссылки на объекты, а не их содержимое. Из-за различий в памяти поведение будет разным.
String s1 = new String("Hello");
String s2 = "Hello";
String s3 = "Hello";

System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true

s1 == s2 -> false, потому что s1 ссылается на объект в куче, а s2 — на объект в String Pool. Это два разных объекта в памяти.
s2 == s3 -> true, потому что обе переменные ссылаются на один и тот же объект в String Pool.
Для сравнения содержимого строк всегда используйте метод equals():
System.out.println(s1.equals(s2)); // true (сравнивается содержимое "Hello")
System.out.println(s2.equals(s3)); // true


▪️ 3. Производительность

🔸Строковый литерал ("Hello") — более эффективен. Он избегает создания дубликатов в памяти, что экономит память и ускоряет работу, так как не нужно создавать новый объект, если он уже существует в пуле.
🔸Оператор new — менее эффективен. Он принудительно создает новый объект в куче, даже если идентичная строка уже существует. Это может привести к избыточному расходу памяти.

▪️ 4. Количество создаваемых объектов

🔸String s1 = new String("Hello"); — Может создать 1 или 2 объекта.
1. Строковый литерал "Hello" сначала ищется в String Pool. Если его нет — он создается в пуле. (Первый возможный объект).
2. Затем ключевое слово new создает новый объект String в куче. (Второй объект).
Таким образом, если строка "Hello" ранее не существовала в пуле, эта строка кода создаст два объекта.
🔸String s2 = "Hello";
Создает 0 или 1 объект.
JVM ищет "Hello" в String Pool. Если находит — объект не создается, переменной присваивается существующая ссылка (0 новых объектов).
Если не находит — создает новый объект в String Pool (1 новый объект).

▪️Метод intern() — мостик между двумя подходами. Метод intern() позволяет вручную поместить строку из кучи в String Pool или получить ссылку на уже существующую там строку.
String s1 = new String("Hello");
String s2 = s1.intern(); // Помещаем строку в пул (или получаем ссылку из пула)
String s3 = "Hello";

System.out.println(s1 == s2); // false, т.к. s1 все еще в куче
System.out.println(s2 == s3); // true, т.к. s2 и s3 ссылаются на один объект в пуле

В этом примере s1.intern() находит строку "Hello" в пуле (которая была создана при вычислении литерала внутри конструктора) и возвращает на неё ссылку, которую мы присваиваем s2.

Практический вывод: Почти всегда следует использовать строковые литералы (String s = "value";). Этот способ более эффективен по памяти и времени, так как использует механизм пула строк. #java #задачи #программирование #собеседования #IT #структуры_данных

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
134👍22🔥72❤‍🔥2👨‍💻21
👩‍💻 Java: А есть ли связь между сравнением строк equals() и хешированием hashCode() ?

В Java существует важное правило (контракт):
1. Если две строки равны по equals(), то их hashCode() ДОЛЖЕН быть одинаковым
2. Обратное не обязательно верно: одинаковый hashCode() не гарантирует равенства строк
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");

System.out.println(s1.equals(s2)); // true
System.out.println(s1.hashCode() == s2.hashCode()); // true

System.out.println(s1.equals(s3)); // true
System.out.println(s1.hashCode() == s3.hashCode()); // true


👩‍💻 Как вычисляется hashCode для String

Метод hashCode() в классе String вычисляется на основе содержимого строки:
public int hashCode() {
int h = hash; // кэшированное значение
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

Вычисляется по формуле: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
Результат кэшируется в поле hash для производительности
Для одинакового содержимого всегда одинаковый hashCode, независимо от того, как была создана строка
value и hash — являются полями класса String и уже существуют в объекте, когда вызывается метод hashCode().
value — массив символов, который хранит собственно содержимое строки. Он инициализируется при создании объекта. String s = "Hello"; // value = {'H', 'e', 'l', 'l', 'o'}
hash — поле для кэширования вычисленного хэш-кода. Оно инициализируется по умолчанию значением 0.

Практическое применение в коллекциях: Связь hashCode и equals критически важна для работы хэш-коллекций:

🔸 HashMap/HashSet
Map<String, Integer> map = new HashMap<>();
map.put("Hello", 1);
map.put(new String("Hello"), 2); // Затрет предыдущее значение!

System.out.println(map.size()); // 1 - потому что ключи равны по equals()

1. Сначала сравниваются hashCode() — если разные, объекты точно разные
2. Если hashCode одинаковые, тогда вызывается equals() для точной проверки

🔸 Оптимизация сравнения
String s1 = "very long string ...";
String s2 = "another very long string ...";

// Сначала проверяется hashCode - быстрая операция
if (s1.hashCode() == s2.hashCode() && s1.equals(s2)) {
// Строки точно равны
}

▪️ 1. Коллизии хэшей — Разные строки могут иметь одинаковый hashCode (хэш-коллизия)
String a = "Aa";
String b = "BB";

System.out.println(a.hashCode()); // 2112
System.out.println(b.hashCode()); // 2112
System.out.println(a.equals(b)); // false

▪️ 2. Производительность

// Медленно - создается новый объект и вычисляется hashCode
String s1 = new String("Hello");

// Быстро - используется кэшированный hashCode из String Pool
String s2 = "Hello";

3. String Pool и hashCode
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");

// Все три имеют одинаковый hashCode, но разные способы создания
System.out.println(s1.hashCode()); // одинаковый
System.out.println(s2.hashCode()); // одинаковый
System.out.println(s3.hashCode()); // одинаковый

🔍 Важные моменты. HashCode тесно связан со сравнением строк через:
1. Контракт Java — равные строки по equals() должны иметь одинаковый hashCode
2.. Оптимизацию сравнения — хэш используется для быстрой предварительной проверки
3. Работу коллекций — HashMap, HashSet и другие используют эту связь для эффективного хранения и поиска
#java #задачи #программирование #собеседования #IT #структуры_данных

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
132👍22🔥8❤‍🔥4👨‍💻3😱1
🧠Логическое мышление: как большие языковые модели научились логическим рассуждениям без больших финансовых и временных затрат.
Исследователи из T-Bank AI Research и лаборатории Центрального университета Omut AI представили метод, который позволяет развивать сложные reasoning-навыки без полного переобучения — своего рода «точной настройке» логических цепочек в уже обученной сети.

В основе подхода лежит не “переписывание мозга”, а steering vectors — компактные векторы-регуляторы, которые усиливают корректные логические шаги модели. На шести математических бенчмарках метод показал сохранение 100% эффективности полного дообучения при изменении всего 0.0016% параметров 14-миллиардной модели. Требования к памяти сократились с гигабайтов до сотен килобайт. Скорость одного из этапов обучения увеличилась с десятков минут до секунд.

Logit-анализ показывает усиление ключевых маркеров логических рассуждений — таких как “потому что”, “следовательно”, “правильно”. В связи с этим поведение LLM становится легче интерпретировать исследователям, которые получают прозрачный инструмент для изучения того, как именно модель рассуждает.

Результаты исследования протестировали на моделях Qwen и LLaMA и представили на EMNLP 2025.

📕Steering LLM Reasoning Through Bias-Only Adaptation

#наука #math #science #программирование #разработка #IT

💡 Physics.Math.Code // @physics_lib
36👍16🔥12🤯4🗿2❤‍🔥1👨‍💻1
This media is not supported in your browser
VIEW IN TELEGRAM
🖥 Сборка мусора (англ. garbage collection) в программировании — одна из форм автоматического управления памятью. Специальный процесс, называемый сборщиком мусора (англ. garbage collector - GC), периодически освобождает память, удаляя из неё ставшие ненужными объекты. Автоматическая сборка мусора позволяет повысить безопасность доступа к памяти. Сборка мусора была впервые применена Джоном Маккарти в 1959 году в среде программирования на разработанном им функциональном языке программирования Лисп. Впоследствии она применялась в других системах программирования и языках, преимущественно — в функциональных и логических. Необходимость сборки мусора в языках этих типов обусловлена тем, что структура таких языков делает крайне неудобным отслеживание времени жизни объектов в памяти и ручное управление ею. Широко используемые в этих языках списки и основанные на них сложные структуры данных во время работы программ постоянно создаются, надстраиваются, расширяются, копируются, и правильно определить момент удаления того или иного объекта затруднительно.

В промышленных процедурных и объектных языках сборка мусора долго не использовалась. Предпочтение отдавалось ручному управлению памятью, как более эффективному и предсказуемому. Но со второй половины 1980-х годов технология сборки мусора стала использоваться и в директивных (императивных), и в объектных языках программирования, а со второй половины 1990-х годов всё большее число создаваемых языков и сред, ориентированных на прикладное программирование, включают механизм сборки мусора либо как единственный, либо как один из доступных механизмов управления динамической памятью. В настоящее время она используется в Оберон, Java, Python, Ruby, C#, D, F#, Go и других языках.

▪️Висячая ссылка (англ. dangling pointer) — это ссылка на объект, который уже удалён из памяти. После удаления объекта все сохранившиеся в программе ссылки на него становятся «висячими». Память, занимаемая ранее объектом, может быть передана операционной системе и стать недоступной, или быть использована для размещения нового объекта в той же программе. В первом случае попытка обратиться по «повисшей» ссылке приведёт к срабатыванию механизма защиты памяти и аварийной остановке программы, а во втором — к непредсказуемым последствиям. Появление висячих ссылок обычно становится следствием неправильной оценки времени жизни объекта: программист вызывает команду удаления объекта до того, как его использование прекратится.

▪️Утечки памяти — Создав объект в динамической памяти, программист может не удалить его после завершения использования. Если ссылающейся на объект переменной будет присвоено новое значение и на объект нет других ссылок, он становится программно недоступным, но продолжает занимать память, поскольку команда его удаления не вызывалась. Такая ситуация и называется утечкой памяти (англ. memory leak). Если объекты, ссылки на которые теряются, создаются в программе постоянно, то утечка памяти проявляется в постепенном увеличении объёма используемой памяти; если программа работает долго, объём используемой ею памяти постоянно растёт, и через какое-то время ощутимо замедляется работа системы (из-за необходимости при любом выделении памяти использовать свопинг), либо программа исчерпывает доступный объём адресного пространства и завершается с ошибкой. 📱 Подробности

📱 Автор видео: Владимир Балун

#программирование #архитектура #многопоточность #сборщикмусора #cpp #java #coding #programming

💡 Physics.Math.Code
// @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
56👍44🔥156👨‍💻3❤‍🔥1🤯1
🧩 Задача на C++: "Таинственная конкатенация"

🖥 Что выведет следующая программа? Будьте внимательны!
#include <iostream>
#define MERGE(a, b) a ## b

int main() {
const char* result1 = MERGE("Hello, ", "World!");
const char* result2 = MERGE("Hello, ", "World" "!");

std::cout << result1 << std::endl;
std::cout << result2 << std::endl;
return 0;
}

Варианты:
1. Обе строки выведут "Hello, World!"
2. Ошибка компиляции
3. Первая выведет мусор, вторая — "Hello, World!"
4. Первая вызовет ошибку, вторая скомпилируется
Задумайтесь на минутку, прежде чем запускать код...

🔍 Разбор проблемы
Правильный ответ: 2 (Ошибка компиляции) или, если точнее, ошибка возникнет уже на строке с result1.
🖥 Код с решением и комментариями:
#include <iostream>
#define MERGE(a, b) a ## b

int main() {
// Эта строка НЕ скомпилируется:
// const char* result1 = MERGE("Hello, ", "World!");
// После раскрытия макроса получим: "Hello, ""World!"
// Это два отдельных строковых литерала без оператора конкатенации

// А вот эта строка скомпилируется и выведет "Hello, World!":
const char* result2 = MERGE("Hello, ", "World" "!");
// После раскрытия макроса получим: "Hello, ""World""!"
// А благодаря фазе трансляции, соседние строковые литералы
// сливаются в один: "Hello, World!!"

// Правильный способ через макрос:
const char* result3 = "Hello, " "World!";

std::cout << result2 << std::endl; // Выведет: Hello, World!!
std::cout << result3 << std::endl; // Выведет: Hello, World!
return 0;
}

📚 Малоизвестный факт:
В C++ есть специальная фаза трансляции, где соседние строковые литералы объединяются в один. Например:
const char* s = "Hello, " "World!"; // Эквивалентно "Hello, World!"
Но этот процесс происходит до раскрытия макросов, поэтому MERGE("Hello, ", "World!") не работает как ожидается.

Ключевые моменты:
1. Оператор ## в макросах выполняет сращивание токенов, а не строк
2. Строковые литералы автоматически конкатенируются на фазе трансляции
3. Макросы раскрываются на более поздней фазе, когда уже слишком поздно для "правильной" конкатенации строк

Будьте осторожны с оператором ## при работе со строковыми литералами! Для их конкатенации лучше использовать обычное расположение рядом или constexpr функции в современном C++.

Чем токен отличается от строки?

1. Токен (в контексте препроцессора C++) — это минимальная единица текста программы, которую распознает препроцессор (
int, main, (, ), {, "Hello", 123, +, ; )
Препроцессор работает именно на уровне токенов. Оператор ## сращивает именно токены, а не их значение

2. Строковый литерал — это конкретный тип токена, который представляет строку в кавычках. Пример: "Hello" — это один токен типа "строковый литерал"


Ещё по теме: Задачки по программированию для наших подписчиков [ C/C++ ]

#C #cpp #cplusplus #программирование #задачи

💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
50👍20🤷‍♂16🤯6🔥4👾4👏1👻1