Круто, я тоже пользовался fiddler'ом, но хотел немного более интеллектуального бота. Поделюсь своей наработкой немного деобфусцированного скипта, правда, одной из предыдущих версий, gist.github.com/abby-sergz/65aad7682de388f14ee2.
В целом большинство моментов справедливы, но аналогия неправильная:
Так же как работа столяра не заключается в использовании молотка или пилы — она заключается в производстве чего-либо при помощи этих инструментов.
Инструменты: молоток и пила — IDE и компилятор. А качество кода — это качество дерева. Если дерево гнилое, то результат работы столяра сломается при первом же прикосновении.
В этом ключе, получается, что код — это не инструмент, а материал. И для хорошего решения как правило требуются определенные свойства материала (каленое железо, сухое дерево, мягкое или жесткое дерево, гладкая поверхность соприкасающихся подвижных частей).
Получение материала с теми или иными свойствами — вот это и есть мастерство.
Поэтому и заказчику или кому бы то ни было нужно не показывать сколько строк написано (сколько дыр просверлено или как гладко отполировали), а объяснять, что отшлифовали те и те детали, и сумели сделать сложное отверстие таким образом, что деталь теперь одна цельная, а это значит, что двигатель сможет нормально работать и не взорвется на презентации.
Поскольку довольно часто встречается такой комментарий, то отвечу на него без иронии.
По моему опыту место для сна, возможно, перебор (как бы это не звучало, оказывается полезно для некоторых гостей), а вот небольшая (или большая) тренажерка, развлечения (типа пинг-понг или еще чего-нибудь) и столовая никак не мешают рабочему процессу, при этом остается время и силы на нормальную личную жизнь.
Тут все просто
развлечения в среднем могут занимать 15 мин в день, иногда до 30 мин, при этом позволяют действительно отвлечься, а так же самое важное — пообщаться с коллегами, с которыми иначе общение само собой не начинается по тем или иным причинам.
столовая, доступная без дождя, очереди и лишнего шума существенно экономит время и деньги, поход в кафе занимает час-полтора, пообедать и пообщаться в своём кафе, как правило, минут 30-40
тренажерный зал. Я заметил, что всякие дополнительные персадки и поездки по пути с работы и на работу довольно сильно утомляют, даже если на машине, то все равно удобнее, чтобы без лишних поездок и хождений. Имея свой зал, улучшается гибкость по времени, исчезают всякие проблемы, типа заботы о вещах, в результате уменьшается утомление.
Еще было бы очень удобно иметь языковые курсы прямо на работе.
Кстати, никто же не запрещает посещать другие заведения, и никто не обязывает пользоваться тем, что есть или тратить время.
Глядя на другие комментари, для меня лично работа не является и никогда не являлась вторым домом, скорее наоборот, пришел в офис, сконцентрировался на своих рабочих обязанностях, сделал что хотел, решил рабочие процессы, остался доволен или недоволен. Вне работы можно со спокойной совестью заниматься своими делами. При этом я не как американцы, для которых работа перестает существовать после шести вечера.
Все это выгодно и работнику, и работодателю, потому что работник успевает разнообразить свою жизнь, лучше развивается, меньше утомляется, лучше сфокусирован, в результате, эффективнее работает, от всего этого лучше себя чувствует, и все по кругу.
ПС: я не имею и не имел никакого отношения ни к ABBYY, ни к Яндексу, ни к другим известным большим компаниям.
Во-первых, такие вещи должны быть обязательно обложены тестами, а, во-вторых, в дизайне и коде есть пара моментов. Самое главное в дизайне — ScopedHandle неудачный пример для производной от Вашего Resource.
Дальше коментарии (возможно, тянут на доп статью) пойдут про ScopedHandle, поскольку статья выше в основном об этом.
— я бы сделал ScopedHandle без предложенного Resource, без std::unique_ptr и ограничился бы поддержкой только тривиальных хендлов (static_assert(std::is_trivial<Handle>::value, "The Handle type should be trivial.");). Это существенно всё упрощает.
— заранее неизвестно, что инициализация ресурса в значение по-умолчанию есть правильно, из этого вытекают всякие моменты почти во всех остальных методах
— так же из первого довольно сильно могут усложниться реализации всяких специфичных производных (речь о using ScopedHandle = Resource<struct HandleTag, Handle>, кстати, неплохо было бы добавить final, вряд ли тут будет к месту наследование, и так довольно сложный фундаментальный класс)
— в качестве конструктора по-умолчанию кажется более логично использовать конструктор с одним аргументом, который принимает resource, и значением по-умолчанию
— нет возможности узнать открыт (валидный) handle или нет
— по моему опыту, публичный метод close оказался очень полезен
— иногда надо иметь возможность получить указатель на уже открытый handle (например, чтобы сложить его в какой-нибудь массив), побочный эффект (side effect), очищающий ресурс тут немного некстати. Это действительно очень спорное решение. В зависимости от ситуации тут может лучше вернуть nullptr, если ресурс уже открыт, вернуть указатель на ресурс без изменений, очистить ресурс (как у Вас) или бросить исключение (пока что во всех моих проектах, я был против варианта бросания исключения).
— неплохо было бы иметь Resource& operator=(ResourceType h)
— operator const ResourceType&() const noexcept { return resource_; } тут вопрос с константностью, допустим у нас константный объект, тогда мы можем получить ресурс (хендл), и изменить его, так как он скопируется при передаче в функцию. Тут философский вопрос о побитовой и логической константности, но все же упомянуть стоит. Я бы лично сделал неконстантным, больше помощи от компилятора.
— для Resource& operator=(Resource&& other) я бы воспользовался swap idiom, но так тоже хорошо.
— отсутствие operator bool() const и размышлений на эту тему.
В этой связи я бы ввёл какой-нибудь traits, например,
Для документации и тем более для статьи обязательно нужно оговорить все моменты закрытия ресурса. Во-первых, состояние после закрытия должно быть рабочим (в Вашем примере неплохо было бы присвоить хендлу спецальное значение), во-вторых, закрытие должно быть строго детерминировано, а, в-третьих, не должны вызываться закрывающие методы от предыдущих ресурсов (у Вас с этим все хорошо на этам дизайна, теги помогают, а мне повезло поработать и с таким кодом).
Я с нетерпением жду этот браузер и Win10 и настроен позитивно, но все же хотел бы оставить пару комментариев
> Субъективно — браузер быстрый, шустрый, без лагов и лажи.
— субъективно — браузер тормозной, часто все как-то рывками или с задержкой
— заметны баги в отрисовке
— какой-то spartan_legacy.exe жрёт 600МБ
— браузер периодически падает
— console и debug в developer tools не работают, и браузер после этого падает
— почему-то иногда только со второго раза может отрисовать страницу со всеми стилями
> Flash и прочие прелести уже встроены.
> По крайней мере в нем нету ActiveX, поверхность атаки определенно уменьшилась.
Подгружается бинарник Flash.ocx, т.е. поддержка нативных расширений есть, но как подключить свой плагин пока точно неизвестно. Где-то говорилось, что расширения будут совместимы с хоромом, но текущий статус нигде найти не удается.
Если честно, то мне лично дизайн не нравится, я не против плоского, но в IE как-то грязновато и ляповато выглядит, и, пользуюясь случаем, настройки ОС — как будто всех дизайнеров уволили.
В любом случае, хорошо, что дали потрогать, теперь хотя бы можно уже ковыряться. Так же видна активная деятельность, так что можно смело сохранять положительные надежды.
А не пробовали applicationName.exe -platform windows:dpiawareness=0 (https://doc-snapshots.qt.io/qt5-5.4/highdpi.html)?
Еще можно попробовать выключить масштабирование на вкладке совместимости.
Инженерное решение отличное, но не лучше было бы не идти так далеко, а остановиться на известном полифиле?
Всем известно чего ожидать от этого полифила и как с ним работать. Тут же, еще одна версия реализации, потраченные человеко-часы на трансляцию XPath в CSS селекторы и новый сложный хак. Именно чтобы избавиться от таких хаков и решили выпустить новую версию.
Мне кажется, что в этой статье не раскрыта суть уязвимости, в результате создаётся впечатление, что опасность в том, что иконка для ярлыка берется из ресурсов исполняемого файла. А это не так, проблема до сих пор в том, что вместо вызова LoadLibraryEx со спецальным флагом вызывается LoadLibrary.
Доп ссылка: habrahabr.ru/post/163409/
> element->getAttribute(L"href", 2, &variant)
Тут еще один баг, IHTMLElement::getAttribute в качестве аргумента ожидает BSTR, а не wchar_t*. На моей практике этот метод не падает, но думаю только потому, что в MS написали дебилоустойчивый код.
Было бы очень интересно почитать о проблемах, с которыми вы столкнулись при разработке как API так и клиента. Наверняка кто-то сломал голову, думая о разрешении конфликтов, к чему Вы в итоге пришли и какие планы? Как и какие проблемы решали и решили ли при отслеживании изменений файлов и папок. Как происходит процедура синхронизации с учетом того, что пользователь в этот момент может сделать что угодно как с файлами, так и убить приложение. И так далее.
Конечно не заметили. Вы же статью прочитали «по диагонали». И тут же не к месту набросились со своим С++.
Во-первых, тон статьи говорит о том, что посмотрите как это легко в Scala и как сложно в C++ или Java, там уж точно придется написать две стриницы кода. Я же, сомневаюсь в такой категоричности. Во-вторых, это не я придумал сравнивать с C++, а автор статьи.
Спасибо за комментарий, но ни о чём таком ни в статье, ни в переводе не написано.
— Насколько я помню, в конце 2011 года auto уже было.
— В C++ есть ключевое слово const, пожалуйста, пусть будет
Извините, я совершенно не знаком с Scala, в итоге, пробежав по вашей статье, никаких преимуществ не заметил. Вижу, что перевод, оригинал так же не содержит ничего внятного.
Вывод типов
Scala:
val aGuy = "John"
C++:
auto theGuy = "Ivan";
Упрощенное определение классов
Scala:
class Person (val firstName:String, val lastName:String)
C++:
struct Person{ std::string firstName; std::string lastName; }; // мне лично такой стиль форматирования не нравится
Преимуществ не видно.
Объединение методов и операторов
Извините, но я не наблюдаю описанных проблем в С++
Scala:
ListBuffer(1,2,3) append 4
или
ListBuffer(1,2,3) += 4
Вообще говоря, += выглядит сомнительно, в контексте какого-нибудь алгоритма иногда можно понять по-другому.
После примера
"Mary" with "a purse" and "red shoes" should look "nice"
, стало доходить, что может быть на самом деле, речь об отсутствии точек и скобочек. Выглядит круто, но только если очень хорошая подсветка синтаксиса, иначе тяжело разобрать что есть что. Тем не менее чего-нибудь такого или типа linq в C++ не хватает.
С++
сразу после старта или добавления записи имеет смысл их показывать, а то надо постоянно кнопку Ctrl+F давить
-вопрос спорный, если их более 1000, смысл их отображать при запуске?
Плюс в версию того, что не нужно их показывать. Для этого можно иметь отдельную «страничку» с областями, содержащими «самое популярное», «недавно добавленное», «недавно просмотренное». Плюс, если включить в покрываемые файлы документы, то нужен поиск по датам. Для книг, возможно, что достаточно только тегов.
Спасибо за статью, но у меня все равно остались вопросы без ответа
— не ясно как уменьшить время, которое тратится на обзор?
— что делать с недобросовестным обзором?
Я полностью за кодревью, и мы это делаем (в терминах этой стать 95% на github'е), но у меня такое чувство, что что-то не так (дальше в описании крик души). Сборки на каждый пулл-реквест автоматически собираются, все тесты прогоняются, если тесты не работают, то и смотреть как правило пока рано.
— Смотрю на стиль (тут обычно проблем не возникает), выясняю как выглядит картина из далека без деталей, иногда несколько замечаний по API, обсуждаем почему так и решаем как должно быть. Не отнимает много времени, просто прочитать код, оценить что да как.
— смотрю на логику, дебажу тесты. Рассматриваю всякие случаи. Тут начинается «а что если ...», и выясняется, что все плохо. Иногда обсуждаем в переписке, иногда устно, но все равно процесс слияния затягивается, да и такого рода проверка занимает довольно длительное время. Как правило, в таких случаях начинаем думать, как бы это так переписать, чтобы проблема устранялась на уровне архитектуры. В итоге, один пулл-реквест может затянутся на несколько дней или даже неделю. В нормальных условиях у меня рука не поднимается смержить код, когда я точно знаю, что программа может сломаться или работать совсем не так как надо. Это же не на коленке один раз запустить, а отправить юзерам. Обычно в таких случаях вешаю пулл-реквест на себя и объясняю, где баг и никто его не мержит, пока все не исправится.
В общем чувствую себя в эти моменты не по-феншую. Показал коллегам, что их код, простите, говно, затянул разработку и потратил кучу своего времени, в итоге и сам мало сделал или ничего не сделал.
Но я же не все реквесты рассматриваю, бывает даже, что я не успеваю разобраться в каком-нибудь новом модуле, ну а там часто описанный ранее случай. У других членов команды другой подход, и они довольно быстро все мержат, я, честно говоря, не верю, что они разобрались как это работает.
Опять чувствую себя как-то не по-феншую, но засовываю свой перфекционизм до следующего креша.
Получается, что я такой дартаньян, хотя, конечно, и я делаю кучу ошибок опечаток и что-то забываю. В команде отношение ко мне нормальное, наоборот считаем, что, чем раньше нашли проблему, тем лучше, но скорость разработки существенно проседает.
Пробовал поговорить с тимлидом, со всеми вместе и с каждым лично по поводу детализации пулл-реквестов, по поводу времени, как мне уменьшить свои траты, а другие бы лучше все проверяли перед пулл-реквестом. В итоге обсуждения получается, что я делаю все правильно, и менять ничего не надо.
Вариант сменить место работы, конечно, можно рассмотреть, но это кажется слишком кардинально, и, насколько я понял из данный статьи, что ребята решают эти проблемы на одном месте. Возможно, что есть какие-то подходы, которые это все помогают сделать. В утилиты не верю. Можно написать все по всем стайл-гайдам, но в итоге ничего работать не будет. В основном это поведение в многопоточной постоянно работающей программе.
Инструменты: молоток и пила — IDE и компилятор. А качество кода — это качество дерева. Если дерево гнилое, то результат работы столяра сломается при первом же прикосновении.
В этом ключе, получается, что код — это не инструмент, а материал. И для хорошего решения как правило требуются определенные свойства материала (каленое железо, сухое дерево, мягкое или жесткое дерево, гладкая поверхность соприкасающихся подвижных частей).
Получение материала с теми или иными свойствами — вот это и есть мастерство.
Поэтому и заказчику или кому бы то ни было нужно не показывать сколько строк написано (сколько дыр просверлено или как гладко отполировали), а объяснять, что отшлифовали те и те детали, и сумели сделать сложное отверстие таким образом, что деталь теперь одна цельная, а это значит, что двигатель сможет нормально работать и не взорвется на презентации.
По моему опыту место для сна, возможно, перебор (как бы это не звучало, оказывается полезно для некоторых гостей), а вот небольшая (или большая) тренажерка, развлечения (типа пинг-понг или еще чего-нибудь) и столовая никак не мешают рабочему процессу, при этом остается время и силы на нормальную личную жизнь.
Тут все просто
Еще было бы очень удобно иметь языковые курсы прямо на работе.
Кстати, никто же не запрещает посещать другие заведения, и никто не обязывает пользоваться тем, что есть или тратить время.
Глядя на другие комментари, для меня лично работа не является и никогда не являлась вторым домом, скорее наоборот, пришел в офис, сконцентрировался на своих рабочих обязанностях, сделал что хотел, решил рабочие процессы, остался доволен или недоволен. Вне работы можно со спокойной совестью заниматься своими делами. При этом я не как американцы, для которых работа перестает существовать после шести вечера.
Все это выгодно и работнику, и работодателю, потому что работник успевает разнообразить свою жизнь, лучше развивается, меньше утомляется, лучше сфокусирован, в результате, эффективнее работает, от всего этого лучше себя чувствует, и все по кругу.
ПС: я не имею и не имел никакого отношения ни к ABBYY, ни к Яндексу, ни к другим известным большим компаниям.
ScopedHandleнеудачный пример для производной от ВашегоResource.Дальше коментарии (возможно, тянут на доп статью) пойдут про
ScopedHandle, поскольку статья выше в основном об этом.— я бы сделал
ScopedHandleбез предложенногоResource, безstd::unique_ptrи ограничился бы поддержкой только тривиальных хендлов (static_assert(std::is_trivial<Handle>::value, "The Handle type should be trivial.");). Это существенно всё упрощает.— заранее неизвестно, что инициализация ресурса в значение по-умолчанию есть правильно, из этого вытекают всякие моменты почти во всех остальных методах
— так же из первого довольно сильно могут усложниться реализации всяких специфичных производных (речь о
using ScopedHandle = Resource<struct HandleTag, Handle>, кстати, неплохо было бы добавить final, вряд ли тут будет к месту наследование, и так довольно сложный фундаментальный класс)— в качестве конструктора по-умолчанию кажется более логично использовать конструктор с одним аргументом, который принимает resource, и значением по-умолчанию
— нет возможности узнать открыт (валидный) handle или нет
— по моему опыту, публичный метод
closeоказался очень полезен— иногда надо иметь возможность получить указатель на уже открытый handle (например, чтобы сложить его в какой-нибудь массив), побочный эффект (side effect), очищающий ресурс тут немного некстати. Это действительно очень спорное решение. В зависимости от ситуации тут может лучше вернуть
nullptr, если ресурс уже открыт, вернуть указатель на ресурс без изменений, очистить ресурс (как у Вас) или бросить исключение (пока что во всех моих проектах, я был против варианта бросания исключения).— неплохо было бы иметь
Resource& operator=(ResourceType h)—
operator const ResourceType&() const noexcept { return resource_; }тут вопрос с константностью, допустим у нас константный объект, тогда мы можем получить ресурс (хендл), и изменить его, так как он скопируется при передаче в функцию. Тут философский вопрос о побитовой и логической константности, но все же упомянуть стоит. Я бы лично сделал неконстантным, больше помощи от компилятора.— для
Resource& operator=(Resource&& other)я бы воспользовался swap idiom, но так тоже хорошо.— отсутствие
operator bool() constи размышлений на эту тему.В этой связи я бы ввёл какой-нибудь traits, например,
Для документации и тем более для статьи обязательно нужно оговорить все моменты закрытия ресурса. Во-первых, состояние после закрытия должно быть рабочим (в Вашем примере неплохо было бы присвоить хендлу спецальное значение), во-вторых, закрытие должно быть строго детерминировано, а, в-третьих, не должны вызываться закрывающие методы от предыдущих ресурсов (у Вас с этим все хорошо на этам дизайна, теги помогают, а мне повезло поработать и с таким кодом).
> Субъективно — браузер быстрый, шустрый, без лагов и лажи.
— субъективно — браузер тормозной, часто все как-то рывками или с задержкой
— заметны баги в отрисовке
— какой-то spartan_legacy.exe жрёт 600МБ
— браузер периодически падает
— console и debug в developer tools не работают, и браузер после этого падает
— почему-то иногда только со второго раза может отрисовать страницу со всеми стилями
> Flash и прочие прелести уже встроены.
> По крайней мере в нем нету ActiveX, поверхность атаки определенно уменьшилась.
Подгружается бинарник Flash.ocx, т.е. поддержка нативных расширений есть, но как подключить свой плагин пока точно неизвестно. Где-то говорилось, что расширения будут совместимы с хоромом, но текущий статус нигде найти не удается.
Если честно, то мне лично дизайн не нравится, я не против плоского, но в IE как-то грязновато и ляповато выглядит, и, пользуюясь случаем, настройки ОС — как будто всех дизайнеров уволили.
В любом случае, хорошо, что дали потрогать, теперь хотя бы можно уже ковыряться. Так же видна активная деятельность, так что можно смело сохранять положительные надежды.
applicationName.exe -platform windows:dpiawareness=0(https://doc-snapshots.qt.io/qt5-5.4/highdpi.html)?Еще можно попробовать выключить масштабирование на вкладке совместимости.
Всем известно чего ожидать от этого полифила и как с ним работать. Тут же, еще одна версия реализации, потраченные человеко-часы на трансляцию XPath в CSS селекторы и новый сложный хак. Именно чтобы избавиться от таких хаков и решили выпустить новую версию.
Доп ссылка: habrahabr.ru/post/163409/
element->getAttribute(L"href", 2, &variant)Тут еще один баг,
IHTMLElement::getAttributeв качестве аргумента ожидаетBSTR, а неwchar_t*. На моей практике этот метод не падает, но думаю только потому, что в MS написали дебилоустойчивый код.Показывает ли Ваш анализатор этот момент?
— Насколько я помню, в конце 2011 года
autoуже было.— В C++ есть ключевое слово
const, пожалуйста, пусть будет — Чем помогают геттеры и сеттеры, сгенерированные компилиятором?Scala:
C++:
Scala: C++: Преимуществ не видно.
Извините, но я не наблюдаю описанных проблем в С++
Scala: C++ (Qt5): Вообще говоря,
+=выглядит сомнительно, в контексте какого-нибудь алгоритма иногда можно понять по-другому.После примера , стало доходить, что может быть на самом деле, речь об отсутствии точек и скобочек. Выглядит круто, но только если очень хорошая подсветка синтаксиса, иначе тяжело разобрать что есть что. Тем не менее чего-нибудь такого или типа linq в C++ не хватает.
С++ <troll-mode>Что скажут любители функциональных языков?</troll-mode>
В C++ вопрос контрвариации и ковариантности действительно не прост, возможно, по этому его как-то неявно избегают, и большой проблемы не ощущается.
Не совсем понятно о чем речь, вроде ничего сложного тут нет.
Вообще эта фича «скалы» выглядит страшновато.
Думаю, что программисты C# еще и не такое покажут.
Плюс в версию того, что не нужно их показывать. Для этого можно иметь отдельную «страничку» с областями, содержащими «самое популярное», «недавно добавленное», «недавно просмотренное». Плюс, если включить в покрываемые файлы документы, то нужен поиск по датам. Для книг, возможно, что достаточно только тегов.
— не ясно как уменьшить время, которое тратится на обзор?
— что делать с недобросовестным обзором?
Я полностью за кодревью, и мы это делаем (в терминах этой стать 95% на github'е), но у меня такое чувство, что что-то не так (дальше в описании крик души). Сборки на каждый пулл-реквест автоматически собираются, все тесты прогоняются, если тесты не работают, то и смотреть как правило пока рано.
— Смотрю на стиль (тут обычно проблем не возникает), выясняю как выглядит картина из далека без деталей, иногда несколько замечаний по API, обсуждаем почему так и решаем как должно быть. Не отнимает много времени, просто прочитать код, оценить что да как.
— смотрю на логику, дебажу тесты. Рассматриваю всякие случаи. Тут начинается «а что если ...», и выясняется, что все плохо. Иногда обсуждаем в переписке, иногда устно, но все равно процесс слияния затягивается, да и такого рода проверка занимает довольно длительное время. Как правило, в таких случаях начинаем думать, как бы это так переписать, чтобы проблема устранялась на уровне архитектуры. В итоге, один пулл-реквест может затянутся на несколько дней или даже неделю. В нормальных условиях у меня рука не поднимается смержить код, когда я точно знаю, что программа может сломаться или работать совсем не так как надо. Это же не на коленке один раз запустить, а отправить юзерам. Обычно в таких случаях вешаю пулл-реквест на себя и объясняю, где баг и никто его не мержит, пока все не исправится.
В общем чувствую себя в эти моменты не по-феншую. Показал коллегам, что их код, простите, говно, затянул разработку и потратил кучу своего времени, в итоге и сам мало сделал или ничего не сделал.
Но я же не все реквесты рассматриваю, бывает даже, что я не успеваю разобраться в каком-нибудь новом модуле, ну а там часто описанный ранее случай. У других членов команды другой подход, и они довольно быстро все мержат, я, честно говоря, не верю, что они разобрались как это работает.
Опять чувствую себя как-то не по-феншую, но засовываю свой перфекционизм до следующего креша.
Получается, что я такой дартаньян, хотя, конечно, и я делаю кучу ошибок опечаток и что-то забываю. В команде отношение ко мне нормальное, наоборот считаем, что, чем раньше нашли проблему, тем лучше, но скорость разработки существенно проседает.
Пробовал поговорить с тимлидом, со всеми вместе и с каждым лично по поводу детализации пулл-реквестов, по поводу времени, как мне уменьшить свои траты, а другие бы лучше все проверяли перед пулл-реквестом. В итоге обсуждения получается, что я делаю все правильно, и менять ничего не надо.
Вариант сменить место работы, конечно, можно рассмотреть, но это кажется слишком кардинально, и, насколько я понял из данный статьи, что ребята решают эти проблемы на одном месте. Возможно, что есть какие-то подходы, которые это все помогают сделать. В утилиты не верю. Можно написать все по всем стайл-гайдам, но в итоге ничего работать не будет. В основном это поведение в многопоточной постоянно работающей программе.
Напоминаю, что вопросы в начале комментария.