Так себе программист
97 subscribers
184 photos
7 videos
1 file
183 links
Меня зовут Александр Троценко. Разработчик, преподаватель, к.т.н. Пишу о программировании и профессии.

10 лет в разработке desktop на C/С++

Контент: https://taplink.cc/atrotsenko
Download Telegram
Изменим тестам и попробуем в угадайку 🫣

Как думаете, чьи логи на картинке?

Ответ под спойлером:
Это кусочек лога веб-сервера Apache. Жмите 🤓, если Apache не угадали, но поняли, что это веб-сервер.

🔥 - угадали
🤓 - угадали только назначение программы
🤷‍♂️ - не угадали
🤓9🤷‍♂4🔥2
Как исследовать exe-файлы с Cutter. Практика обратной разработки

Раз был проявлен интерес к обратной разработке, публикую небольшую статью ⬇️, которая рассказывает на практическом примере как исследуются и патчатся exe-файлы. Подходит для новичков.

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

https://mediocre-developer.ru/kak-issledovat-exe-fajly-s-cutter-praktika-obratnoj-razrabotki
🔥3
int main( int argc, char* argv[] )
{
// ...
return 0;
}
Предлагаю отметить лишний рабочий день расслабляющей угадайкой! 🎉

Знаете, что это на картинке?
Определённо что-то из прошлого.

Ответ под спойлером:
Это перфокарты для электровикторины на знания правил дорожного движения. Фото прибора для считывания перфокарт скину в комменты.

🔥 - угадали
🤷‍♂️ - не угадали
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🤷‍♂2
Законы оптимизации по Фленову

Фленов М.Е. в своей книге "Программирование на C++ глазами хакера" выделил 9 законов оптимизации программ. И хоть сами законы определены немного размыто и многословно, из них можно выделить короткие правила.

1. Оптимизировать можно всё. Даже если вам кажется, что уже нельзя.

2. Первое, с чего нужно начинать, — это поиск самых слабых и медленных мест.

3. Следующим шагом нужно выявить повторяющиеся операции. Начинаем оптимизацию именно с них.

4. Оптимизировать одноразовые операции — это только потеря времени.

5. Старайтесь поменьше использовать вычисления с плавающей запятой. Любые операции с целыми числами выполняются в несколько раз быстрее.

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

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

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

9. Не используйте длинных указателей вроде: ClassName->SubClass->SubSubClass->Property. Если в функции происходит несколько обращений к такому свойству, то это будет неэффективно. Каждый раз компилятор должен развертывать эту длинную цепочку для получения адреса переменной. Намного эффективнее будет завести локальную переменную в начале функции, присвоить ей значение и использовать локальную переменную.

10. Для сложных расчетов можно подготовить таблицы с заранее определенными результатами и потом использовать эти таблицы в реальном режиме времени.

11. Лишних проверок не бывает. Если вы думаете, что какая-то нестандартная ситуация может и не возникнуть, то она не возникнет только у вас.

12. Обязательно делайте проверки всего того, что вводит пользователь. Делайте это сразу же и не ждите, когда введенные данные понадобятся.

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

14. Не переусердствуйте с оптимизацией. Слишком большие затраты на ускорение выполнения кода могут свести на нет приложенные усилия.

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

При этом преждевременно пессимизировать тоже не стоит.

📍 Фленов МЕ - Программирование на С++ глазами хакера (2009)
👍4
Метрики исходного кода

Прогнал проект EduCad, который мы разрабатываем вместе со студентами, через анализатор метрик кода SourceMonitor. Метрик там много: подсчитываются строки, классы, методы, выражения, уровни вложенности, относительные величины и т.д.

По результатам анализа можно сказать, что мы ударно поработали! За 2023/2024 учебный год исходный код проекта неплохо "поправился":

🔜 количество файлов выросло со 123 до 350,
🔜 количество строк выросло с 3446 до 23103,
🔜 увеличилась и доля комментариев с 0,4% до 16,4% (задокументировали API).

Но тут интересно не только посчитать строки, но и выявить потенциально проблемные места в коде. Как правило, я обращаю внимание на:

🔜 Классы с большим количеством строк или методов. Здесь иногда оказывается, что класс определяет более одной сущности.
🔜 Методы с высоким уровнем вложенности. Большие "лесенки" из кода сложно читать и обсуживать. Лучше это не запускать.
🔜 Методы с высоким индексом сложности. Индекс сложности рассчитывается по специальной формуле. Чем выше индекс сложности, тем тоже сложнее читать и обслуживать код.

Относительно пунктов выше, нашему проекту слегка поплохело. Будем над этим работать.

Вообще, для анализа метрик я давно использую SourceMonitor. Это довольно старый проект, который после 2015 года не развивался. Но с недавних пор энтузиасты пытаются его оживить как опенсорс. Как-нибудь попробую собрать их версию.

А вы используете анализаторы метрик кода? Может знаете что-то получше SourceMonitor?
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
YouTube Analyzer 4.0

Выпустили новую версию YouTube Analyzer - анализатора поисковой выдачи YouTube.

Из интересного в коде по сравнению с предыдущей версией:

🔜 Добавлена инфографика для упрощения аналитики: круговые диаграммы и гистограммы. Реализовано на QtCharts.

🔜 Добавлен выпадающий список автозаполнения поискового запроса. Работает как и на самом ютубе: начинаешь вводить запрос, а снизу выпадает "предложка". Реализовано прямо на QLineEdit, у которого из коробки есть возможность установить QCompleter.

YouTube Analyzer - это классическое desktop-приложение, написанное на Python / PySide(Qt).
Его решения можно использовать как шаблон для своих приложений на Python / PySide или на C++ / Qt (API там идентичное)
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Подсчет точек принятия решения

В посте по метрикам я упомянул некий индекс сложности, с помощью которого анализатор SourceMonitor характеризует сложность кода. Этот индекс основан на формуле, подсчитывающей точки принятия решения, описанной в книге Макконнелла "Совершенный код".

Способ подсчета примерно такой:
1. Начните считать с 1 на некотором участке кода.
2. Добавляйте 1 для каждого из следующих ключевых слов или их эквивалентов: if, while, repeat, for, and, or.
3. Добавляйте 1 для каждого варианта в операторе case.

Попробуйте этим способом посчитать количество точек принятия решения для этого кода. Ответ дайте в опросе ниже.
if ( ( status = Success ) and done ) or
( not done and ( numLines >= maxLines ) ) ) then ...
Сколько точек принятия решения в коде выше?
Anonymous Quiz
21%
4
42%
5
21%
6
16%
7
Циклы против алгоритмов в C++

Есть мнение, что нам нужно избегать использования обычных циклов в угоду стандартным алгоритмам C++. Причина простая: семантика (смысл). То есть код, построенный на стандартных алгоритмах, проще читать, а значит проще поддерживать, а значит меньше будет багов. Звучит здорово, но всегда ли это так?

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

Вариант с циклом выглядит так:
for ( Object* obj : list )
{
if ( obj == target )
{
obj->activate();
return;
}
}


А теперь то же самое, но через алгоритм:
auto it = std::find_if( list.begin(), list.end(), [target]( Object* obj )
{
return obj == target;
} );

if ( it != list.end() )
( *it )->activate();


Что скажете, какой вариант проще читать? На мой взгляд вариант с циклом выглядит полегче. Хотя вариант с алгоритмом std::find_if лучше демонстрирует намерение программиста ...наверное 😒

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

📍Don’t use raw loops
👍3
Белое проклятие

"Белое проклятие" - так называется повесть Владимира Санина о работе лавинщиков. Тех, кто изучает лавины и обеспечивает безопасность на горных склонах ⛷

Вообще, мне нравится читать о людях из разных профессий. Особенно экстремальных. После таких историй "шатающийся" прод кажется вполне себе решаемой проблемой 😀

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

В повести непривычно много "технических" моментов по предмету. Я, например, не знал, что лавина толкает перед собой мощную воздушную волну, которая иногда бывает разрушительнее самой снежной массы. Также описана целая инструкция по выживанию при попадании в лавину. Спойлер: шансов мало.

Мастрид, короче)

Я же под впечатлением от прочитанного сообразил вам тест на оценку. Скролим вниз ⬇️

Хотя погодите! Я напомню, что иногда мы здесь практикуем навык оценки. Он нам пригодится для оценки объемов работ и трудозатрат в задачах на разработку. Задачи бывают разные и нам приходится оценивать то, о чем мы имеем слабое представление. Но всегда можно найти факторы, за которые можно зацепиться и, плюс-минус, приблизиться к истине.

#КнижнаяПолка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Дайте оценку, какую часть суши Земли составляют лавиноопасные регионы?
Anonymous Quiz
21%
0.5% - 2.9%
52%
4% - 11%
18%
16% - 27%
9%
28% - 37%
🤩1
Как работать с пул-реквестами в личном репозитории GitHub

Обычно в инструкциях по пул-реквестам GitHub рассматривают примеры на базе форков. Мы же попрактикуем работу с пул-реквестом исключительно в пределах личного репозитория.

С одной стороны, работать в личных репозиториях через пул-реквесты кажется избыточным. Куда проще коммитить в репозиторий напрямую.

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

Читайте полную статью в лонгриде:
https://mediocre-developer.ru/kak-rabotat-s-pul-rekvestami-v-lichnom-repozitorii-github

Также в этот раз я подготовил видео-версию:
📱 YouTube | 📱 ВКонтакте
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
#include <iostream>

class A
{
public:
A() : m_a( 10 ) {}
A( A& from ) : m_a( from.m_a ) {}
virtual int value()
{
return m_a;
}
protected:
int m_a;
};

class B: public A
{
public:
B() : m_b( 20 ) {}
B( B& from ) : m_b( from.m_b ) {}
virtual int value()
{
return m_b;
}
protected:
int m_b;
};

template<class T>
T* CreateCopy( T* from )
{
return new T( *from );
}

int main()
{
A a;
B b;
A* aCopy = CreateCopy<A>( &a );
A* bCopy = CreateCopy<A>( &b );
std::cout << aCopy->value() << " " << bCopy->value();
delete aCopy;
delete bCopy;
return 0;
}
🤯4
Выше дан код на C++. Какой вывод будет у программы?
Anonymous Quiz
14%
10 20
27%
10 10
18%
Никакой. Ошибка компиляции
41%
Неопределенное поведение
😢5
Коллектив в творчестве Санина

Да, опять Санин. Но не могу не поделиться этой заметкой. Большой заметкой. Надеюсь, осилите и даже дополните.

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

Итак, к тезисам 👇

🔜 Подбор коллектива

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

🔜 "Дистанция" руководителя от подчиненных

Коллектив, по сути, состоит из двух сторон: руководитель и подчиненный. Стороны могут как дружить, так и противоборствовать. Одна из причин напряженных взаимоотношений - это желание руководителя "держать дистанцию" от подчиненных.

Опыта и личного мужества у него не отнимешь, всю полярку прошел с низовки, во всех переделках побывал, а зимовать с ним не любили. Почему? Трудно сказать, какие-то штрихи, пустяки. Ну, хотя бы то, что за общий стол не садился, подчеркивал дистанцию. Или с самого начала зимовки выбирал человека послабее и делал из него "мальчика для битья". Или: спиртное разрешал коллективу только по праздникам, а себе - когда появлялось желание.
Санин В.М. "В ловушке"
Кстати, похожий момент про "дистанцию" я видел в фильме "Ледокол". Там какие-то матросы посмеиваются между собой над своим капитаном из-за того, что он не гнушается рядовой работы вместе со всеми остальными. Мол их учили, что капитан должен "держать дистанцию". Позже они получают желаемое. Текущего капитана снимают и назначают вместо него человека с установкой по "дистанции". После этого жизнь на судне заиграла совсем другими красками. "Дистанция" никому не зашла.

🔽
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🔼

🔜 Не каждый должен быть руководителем

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

- Видишь ли, Веня, я просто не гожусь в руководители. Я уже давным-давно определил свои возможности: довольно квалифицированный полярный метеоролог, ну, если очень потребуется, - максимум - заместитель начальника зимовки.
- Не понимаю, чем вы хуже Семёнова...
- Могу сказать. - Гаранин улыбнулся. - В нем есть решительность, дерзость, которых у меня нет. Он прикажет там, где я смогу только просить. Он из тех, кто поднимает в атаку, а я - кого поднимают.
Санин В.М. "В ловушке"


Но "решительность, дерзость" - это одно. А другое - необходимость принимать решения, что тоже останавливает иных идти в руководители:

Впрочем, помощники сплошь да рядом бывают и способнее, и умнее своего капитана, работают больше и спят меньше, но лишь самые дальновидные из них понимают, что участь капитана куда тяжелее: решения принимать ему. И морщин, и седины у Мастера больше, чем у его штурманов, если он даже и не старше их: ибо ничто так не сжигает человека, как необходимость решать. Бывает, пока его примешь, такое решение, месяц жизни проживешь в одну минуту.
Санин В.М. "Трудно отпускает Антарктида"


"Поднимать в атаку" тоже надо уметь. Найти нужные слова, донести идею, зажечь:

Но подлинное чувство долга овладевает человеком лишь тогда, когда исчезает сомнение.
"Собаку накорми, человека убеди, - говорил Георгий Степаныч. - Поверит - море переплывет, не поверит - в луже утонет".
Санин В.М. "В ловушке"

Как ничтожная пылинка может остановить механизм часов, так одно непродуманное слово может непоправимо расколоть коллектив. Одно слово - и вспыхнут страсти! А страсти как ветер на море: может надуть парус и спасти, а может и опрокинуть, утопить лодку - все зависит от того, кто стоит на руле...
Санин В.М. "За тех, кто в дрейфе"


🔽
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🔼

🔜 Коллектив не без недостатков

Раз литература художественная, то конечно же все повести насквозь пронизаны драмой, проблемами, конфликтами и прочим. Иначе было бы просто скучно. Но и в нашей жизни мы вряд ли найдем коллектив без недостатков:

Если под идеальным коллективом понимать группу людей, у которых нет недостатков, то такого коллектива нет и быть не может. Человек без недостатков безлик и скучен, как унылый, позабытый людьми заболоченный пруд; соблюдая букву неписаных правил человеческого общежития, он становится не личностью, а эталоном, которому место не в общежитии, а в музее.
Санин В.М. "Трудно отпускает Антарктида"


А если кажется, что у кого-то недостатков совсем нет, то вы их просто плохо искали 😁

... Одно скажу, бойся людей без недостатков: десять к одному, что они ловко их скрывают. Люди же, которые своих недостатков не прячут, по крайней мере честнее...
...
Самое трудное - понять человека, подумал Семенов. В деле ошибся - сам виноват, а если в человеке - значит он что-то от тебя прятал, не всю душу показывал. То есть вина с тебя все равно не снимается, но и человек, заставивший тебя ошибиться, несет свою долю ответственности.
Санин В.М. "За тех, кто в дрейфе"


Еще заметил у "Санинских" начальников особенное отношение к проступкам своих ребят. Главными виновниками они часто считают не провинившихся, а себя:

Железным принципом Пашкова было никогда не корить подчиненных за проступки, совершенные в его присутствии: видел, что водитель разошелся, не унял его - сам виноват.
Санин В.М. "Точка возврата"

Думаю, на этом достаточно. И так слишком много букв со всякой философией 🤓
Держите 👍 все, кто дочитал)

А что вам нравится или не нравится в вашем коллективе?

P.S. Коллектив... Слово то какое, вспомнил же. Кажется, что я его со школы больше и не слышал ни разу.

#КнижнаяПолка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2