Lex Kravetski (lex_kravetski) wrote,
Lex Kravetski
lex_kravetski

Category:

Логика неизбежности

Шаг первый



Я — профессионал, мастер своего дела и вообще. Пока эти не умеющие проектировать долбодятлы пытаются как-то выкрутиться, я солидно и по-взрослому выстраиваю архитектуру проекта так, чтобы никаких ошибок с управлением памятью не возникало. Мне, с моим развитым интеллектом и широким кругозором, не тяжело сначала подумать, а потом сделать, поэтому связки new-delete вполне достаточно. Я ж не быдлокодер какой.

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

Кстати, а вот отличная идея: надо завести класс DeleteOnExit и ему передавать указатели — кандидаты на зачистку. DeleteOnExit мы будем заводить по значению, поэтому при выходе из функции он удалится — мы ж вышли из его области видимости. А в деструкторе DeleteOnExit мы напишем delete для переданного ему объекта.

Вот что значит знание языка: пока эти дебилы выворачивались, я, с моими знаниями, сразу сообразил, как сделать необходимое. Это потому что интеллект и руки прямые!


Шаг второй



Чего я тут подумал-то. Вот есть у меня класс. В его конструкторе создаётся десяток объектов. А потом они удаляются в деструкторе. Если я эти объекты оберну в мой DeleteOnExit, то ведь они тогда сами будут вместе с родительским объектом удаляться. А что, удобно. Вот что значит системный подход! Нашёл решение и сразу же его применил. Называется «повторное использование». Поняли, ламерьё, как надо-то? Это вам не быдлокодить, это — торжество разума.


Шаг третий



Позвонил один знакомый и сказал, что им срочно нужен ещё один программист. Предложил на полставки после института у них подрабатывать. Ну так а то! Знают, где профессионалов искать!

Согласился. Вышел на работу и сразу охренел. Нет, я, конечно, подозревал, что Фотошоп какой имеет более длинный код, чем моя утилита, отслеживающая изменения в директории, но что б настолько! Да такого размера код за всю жизнь не просмотреть, зараза. Это ж надо так много написать! Я ж теперь уже наверно не смогу каждый день все строки кода перепроверять. А у них тут в архитектуре, со слов главного программиста, бардак полный: здесь создали объект, туда на него указатель передали, а оттуда он ещё вон туда ушёл. По ходу, архитектурой эти лохи вообще не владеют.

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

Сделал функцию и вписал в неё мой DeleteOnExit. Ничего так. Подход рулит. Но во второй функции оказалось, что указатель на объект надо наружу передать. Хотел ведь поначалу отрисовку прямо у себя сделать, но главный программист сказал, что так нельзя, что у них для отрисовки целая иерархия объектов используется, и я должен в неё как-то свой объект передать. На хрена, интересно, им такая иерархия? Чего бы сразу на месте не нарисовать-то? Но спорить не стал. Не люблю конфликты

В общем, объект должен уйти в их иерархию. А где его тогда удалять прикажете?

Проанализировал задачу, снова поразился, как много у них всего написано. Понял, что DeleteOnExit тут не прокатит. Придумал: этот объект мы положим в хранилище объектов, которое я сделаю, а там каждый объект будет обёрнут в DeleteOnExit. При удалении хранилища, удалятся и все объекты в нём. А в функции объект будем класть в хранилище. Вот что значит — системный подход. Это вам не быдлокодить.


Шаг четвёртый



Так всё хорошо шло и всё испортили. Я было наловчился складывать все объекты в хранилище, но неожиданно оказалось, что некоторые объекты могут удаляться и раньше. Их, оказывается, можно через специальный диалог этого типа Фотошопа стереть навсегда. Переделал хранилище, чтобы можно было и до его удаления некоторые объекты удалять, но delete теперь в двух местах. Иногда в одном их них возникает null pointer exception. Почему — неясно. Сложная у них всё-таки архитектура. У меня проще была. Я ж всё-таки не быдлокодер. Я — настоящий мастер своего дела.

В общем, придумал: пусть будет специальный объект, в котором другие объекты создаются и удаляются. delete в этом случае написан только в одном месте и мы всегда там можем запомнить ещё не удалённые объекты. Поэтому delete вызовем ровно один раз. А для уже удалённых delete просто будем пропускать. Всё проще, чем разбираться со всеми возможными последовательностями вызовов. Эх, всё-таки я — молодец. Другой бы не додумался.


Шаг пятый



Коллега сказал, что сделанное мной называется «фабрика». Неужели такое кто-то уже придумал? Странно. Ну да ладно, пусть, я не гордый. В общем, с фабрикой стало гораздо проще. Но и тут вдруг встретилось неразрешимое противоречие — теперь иногда delete не вызывается вообще. Ну, оказалось, что есть ещё несколько мест, куда мои объекты надо передавать, поэтому удалять объект просто по запросу из диалога-удалятора нельзя, надо дождаться, когда его и из других мест тоже удалят.

Поразмыслил и всё понял. DeleteOnExit пусть на всякий случай вызывает удаление через фабрику, но сам при этом считает, в скольких местах про этот объект всё ещё помнят. Когда про него помнить перестанут, вот тогда-то всё и удалится. При удалении моего хранилища, правда, всё удалялось раньше времени, а я так и не нашёл правильное место, куда удаление хранилища вставить. Слишком сложная у них всё-таки архитектура. Не то, что у меня. В общем, от хранилища пришлось отказаться. Всё, значит, хранить в DeleteOnExit — он ведь всей полнотой информации теперь обладает.

Тяжело только разрулить одну ситуёвину: я, прежде чем передать указатель куда-то, у DeleteOnExit вызываю у него increment, чтобы, значит, количество мест, где объект знают, увеличить, а вот когда у него decrement вызвать — неясно. Самое плохое, из некоторых мест мой указатель уже безо всяких инкрементов дальше передаётся. То есть, я не все места помню, где мой указатель есть. Повписывал decrement где надо в коде, но хрен знает, все ли это места? Да и выглядит длинновато: кругом проверки, мой ли это указатель. Надо бы договориться, чтобы все DeleteOnExit повсюду передавали, а то неудобно. Отличная ж идея.

Только надо бы этот объект переименовать. А то он теперь совсем не DeleteOnExit. Надо чего-то типа «считающийся указатель» сделать. IncDecPointer, как-то так.


Шаг шестой.



Пообщался на форуме с каким-то чуваком. Он мне сказал, что такой поинтер уже давно придумали и реализовал я его не совсем правильно — не учёл ряд нюансов. Дал посмотреть, как надо. Оказалось, нужный объект уже даже в библиотеке есть. Кругом меня опередили. Не понимаю, одни ж быдлокодеры повсюду, а что я ни придумаю, оно есть уже. Даром что ли столько времени язык изучал? Думал, вообще всё знаю. Даже про сборщики мусора из-за которых всё тормозит. А вон оно как. Ну да ладно, я не гордый, пусть уже придумали — не могу же всё я один придумывать-то. Столько нюнасов — жизни не хватит. Моё дело — общая концепция. А детали пусть былокодеры делают.

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

Блин, ну надо же как-то было подумать перед проектом, архитектуру разработать. Не знали они, блин! Надо ж узнать сначала, а не сразу кидаться быдлокодить! Я, вот, всегда заранее продумываю архитектуру и прочие детали. Потому что я — профессионал.

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

Код огромен. Если я сейчас возьмусь менять везде указатели на смартпоинтеры, у меня наверно года два уйдёт. Поменял только в тех местах, где с моим кодом взаимодействие идёт, да и то не везде, поскольку в некоторых случаях было неясно, как менять. Мысленно проклял главного программиста: если чувак знал, что смартпоинтеры не везде, чего, нельзя исправить было что ли? Я теперь, как дурак, должен два года потратить на переделку? Да ну нафиг!

Итить! Кабы с самого начала всё на смартпоинтерах делали — проблем бы не было.


Шаг седьмой



Опять всё стало накрываться медным тазом. Нашёл случай, когда смартпоинтер тоже не срабатывает. Есть у меня, значит, одно хранилище, которое внутри себя содержит несколько объектов. Но эти объекты знают, в каком хранилище они хранятся. У них смартпоинтеры на хранилище, а у хранилища — на них. В результате ни хранилище, ни объекты не удаляются. Хорошо вовремя заметил — эти хранилищи у меня создаются в промышленных масштабах для промежуточных операций. Я-то надеялся, что они удаляться будут сами, но нет, не удаляются.

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

Много думал. Вроде бы началось с того, что я не хотел писать delete. Нашёл отличный способ. Даже несколько отличных способов. Но теперь вынужден вместо delete вызывать очистку хранилища. Как-то не очень здорово получилось. Есть в этом какой-то подвох. Тем более, уже появились места, в которых ровно как с былым delete-ом неясно, в какой момент вызывать очистку. Подумал, что наверно нужна некоторая фабрика, которая будет запоминать все неудалённые хранилища и вызывать delete только в тех случаях, когда хранилище ещё не удалено. Но внутренний голос подсказал, что с этим будут какие-то проблемы.

Посоветовался со знакомым. Тот предложил завести глобальный объект, в котором все смартпоинтеры будут себя регистрировать. А тот будет как-то проверять, не только остались ли ссылки на этот объект, но ещё и нет ли ситуации как с хранилищем. Если есть, то в смартпоинтерах счётчик ссылок обнулять. Решению очень обрадовался. Я всегда говорил: главное — системный подход. Именно его не хватает быдлокодерам.

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

Несколько дней рисовал схемы на бумажке — ни фига непонятно. Идиотская какая-то идея, похоже. Вообще не решаемая. Даже я не смог решить.

Позвонил знакомому и сообщил, что он — идиот. Тот повесил трубку. Как есть — идиот. Зашёл на форум и там спросил. Мне какой-то козёл написал, что я — ламер. Целый день с ним ругался, пока меня там админ не забанил. По ходу, у них там целый питомник ламерья. Зашёл на другой форум, где меня знают как профессионала и никто не сможет сказать, что я ламер. Спросил там. Ответа не получил. Ну а собственно, чего я ждал-то? Я ж знаю, что там одни дилетанты собираются. Я ж сам им неоднократно писал, какие они все лохи. Такие вопросы задают, что читать смешно. Знания по нулям вообще.

Обратился к главному программисту с вопросом. Тот хмыкнул и посоветовал хранить в смартпоинтере ссылку на родительский смартпоинтер. Я не понял, как это поможет, и переспросил. Он сказал зайти через полчаса, а когда я зашёл, дал мне готовый класс. Надо же — соображает. А я-то думал, он такой же ламер, как и все вокруг. Правда, если он не ламер, то зачем нанял столько непрофессионалов? Ну да ладно. С моей помощью, надеюсь, всё наладится.

В данном мне объекте содержались комментарии по его использованию. Хм. А это даже удобно — с комментариями. Раньше я считал, что они — для лохов. Что по коду настоящий профессионал и так всё поймёт, но у главного тут получилось как-то непонятно. Я только по комментариям понял, как вообще этим всем пользоваться. То есть, когда программист неразборчиво пишет, комментарии всё-таки полезны. Я, конечно, пишу разборчиво, но ведь действительно, от других такого ожидать нельзя.


Шаг восьмой



Просмотрел класс главного программиста до конца. В конце была обидная приписка, что такие штуки вообще-то надо запускать в отдельном Thread, однако лично он сомневается, что я такое осилю. Он меня совсем за дурака держит? Думает, я не знаю, как использовать Thread?

Полез в интернет читать, как его использовать. Идиотская концепция — вообще ничего непонятно. И кто только такое придумал? Ощущение, все программисты на архитектуру болт кладут.

Читал три дня. Попробовал переписать код главного программиста с Thread-ом — программа через минуту виснет. С чего — неясно. Когда не виснет, объекты исчезают сами собой. Иногда появляется по две штуки сразу. Полный бардак. Подозреваю, этот Thread настолько криво написан, что постоянно бьёт чужую память. Ламерьё кругом.

Позвонил знакомому и извинился, что нагрубил в прошлый раз. Спросил, не знает ли он, где найти Thread без багов. Тот в ответ спросил, зачем мне. Я в общих чертах обрисовал свою задумку. Знакомый сказал, что объяснять долго, поэтому он мне сейчас пришлёт ссылку. По ссылке был уже готовый код того, что я придумал. Я очень удивился: и тут обскакали. Ну надо же. Ламер на ламере, а гляди ж ты! Наверно массой берут.

Скопипастил код себе. Заменил название. Эта штука зачем-то называлась GarbageCollector. Как будто они не знают, что Garbage Collector — это тот адский отстой, из-за которого ублюдочная Java тормозит. Я эту штуку назвал SmartPointerManager. Чтобы не порождать ненужных ассоциаций с быдлокодерством.


Шаг девятый



С этой штукой всё стало заметно подтормаживать. Полез на тот сайт, откуда я её взял, чтобы сообщить им, что они — ламеры криворукие и вообще прогать не умеют, однако наткнулся на приписку, которую в прошлый раз не заметил. Оказалось, это у них — пример. Который они дали для общего раскрытия общего подхода. А на самом деле ко всему этому надо ещё до фига всякого приписать: какие-то там сегментации, отслеживание времени жизни, мониторинг нагрузки, ещё чего-то. Тогда тормозить, говорят, не будет. Такая переусложнённая концепция — я в шоке. На сайте утверждают даже, что такое лучше прямо на уровне языка делать. С этой идеей согласен: SmartPointerC++ неплохо было бы заиметь.

Ещё говорят, указатели вообще тогда лучше не использовать, — ну а то я не знаю! Не даром же я начал везде смартпоинтеры писать.

Спросил главного программиста, тот ответил, что логика неизбежности такова: кто бы ни начал с DeleteOnExit, рано или поздно придёт к сборщику мусора, однако сходу его написать весьма сложно. Сборщик мусора — долбануться. Он, по ходу, тоже не знает, что из-за сборщика мусора Java как раз и тормозит. И на голубом глазу даёт такие советы. Грамотный программист с правильным подходом к архитектуре ведь и так сумеет организовать управление памятью.

Рассказал ему про идею SmartPointerC++. Он не ответил, но как-то нехорошо на меня посмотрел. Очень обидно как-то. Хотел ему нагрубить, но не стал. Не люблю конфликты.
Tags: программирование, философия, юмор
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 171 comments
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →