Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
283 - Telegram Web
Telegram Web
У меня есть pet проект, и одной из кор фичей в которой это тиндоровские карточки. Сами карточки сделала моя подруга, я присоединился к этому проекту позже. Сделала она карточки достаточно круто: отзывчивая анимация, работает все плавно, красиво меняются цвета. Однако карточки получились нефига не расширяемые, крайне не удобно со стороны API. Например, сделать несколько типов разных карточек уже тяжело.

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

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

Так делов не будет, подумал я, психанул и сделал свои карточки, которые работают на базе LazyLayout. Без дерганий и костыля в виде двух Box рисующихся друг на друге. Подробно описывать принцип работы я тут не буду, если стало интересно прошу в мой Github. Если еще звезду накинете, вам вообще вселенский респект будет.

А сейчас смотрите под ноги, потому что я собираюсь выбросить немного мудрости.

Если начинаете делать pet проект, все что можно сделать с помощью либ, делайте при помощи либ. Когда уже проект взлетит будете думать о том, от каких зависимостей лучше избавится и т.д, а в начале не занимайтесь фигней. Как минимум я за вас уже решил еще одну проблему.

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

Ну и последнее, самые крутые решения для open source проектов получаются при решении какой-то конкретной проблемы на реальном проекте. Поэтому если хотите сделать крутую либу для open source, найдите боль в своем проекте, которую почему-то нельзя решить при помощи готовой либы и вуаля, ничего не нужно будет выдумывать.
Многие меня спрашивают, а как у тебя получилось достигнуть успеха в IT? На самом деле никто такое не спрашивает, но хотелось начать как-то пафосно. И ответ на этот вопрос, потому что я часто проебываюсь! Теперь подробнее.

Я вообще в универ пошел на факультет робототехники. Звучит круто правда? По идее нас должны были учить делать всякие манипуляторы, которые бы перекладывали вещи с места на место, а в итоге научили перекладывать ответственность.

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

Наигравшись с электроникой, я начал увлекаться программированием. Увлекло меня как минимум две вещи:
👉 Если ты накосячишь, тебя поправит компилятор. Причем современные компиляторы языков программирования вроде rust еще и ошибки памяти могут отследить. Тут моя невнимательность и кривые руки нивелируются максимально.
👉 Можно косячить сколько угодно. У тебя количество запусков программы ограничивается лишь твоим временем. Хоть заошибайся вдоволь.

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

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

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

Первую статью закинули в наш Android чатик компании, с припиской поделится мнениями. Меня это не на шутку удивило, на самом деле разозлило. За последние лет 5, никто ничего концептуально нового для многомодульной архитектуры не придумал. Все эти статьи буквально пересказ предшественников и в 2023 году на серьезных щах обсуждать эти подходы это блять смешно. Вот серьезно идите посмотрите доклад Неклюдова, а потом прочитав эти статьи ответьте на вопрос, много нового они привнесли?

Вот знаете же миф о том, чтобы разработчику оставаться на одном месте ему нужно постоянно учиться. Я вот уже давно не читаю статьи по мобильной разработке и все жду того момента, когда ничего не буду понимать. За последние 5 лет самым значимым изменением было внедрение compose. Но это всего лишь один UI слой, не говоря уже о том, что большие проекты только-только начинают на него переезжать и то с большим скрипом.

Архитектуры в мобилке до жути простые и они везде одинаковые в 90% случаев. Оставшиеся 10% это какие-нибудь рибс, и то по сути те же яйца, только в профиль. Я даже не уверен, что имеет смысл говорить об архитектуре модулей когда речь идет о мобильном приложение. У бэкендеров другое дело, у них реально миллион способов связать сервисы друг с другом и там имеет место обсуждение архитектур. Потому как проеб в архитектуре у бэкендеров это реальная потеря бабок.

Больше всего забавляет архитектурная секция, где тебя просят сделать архитектору обычного мобильного приложения, у нас в компании такая есть. Хотите я за пару абзацев научу вас ее проходить?

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

Затем вы собираете требования по фичам проекта и тупо отдельные фичи располагаете в разных модулях. Делаете модуль app, показываете что там есть di, затем добавим модуль навигации, ну а че бы и нет. Дальше у вас только два варианта как располагать модули. Либо всю бизнес логику делать внутри feature и если нужно шарить делаете api модуль с интерфейсами, либо делаете отдельные domain модули в которых уже будут всякие repository и interactor.

Дальше желательно сказать что проксирующие интеракторы это херня из под коня и если интервьюер адекватный, ему это понравится. Дальше вам лишь нужно выбрать уже готовую архитектору для Presentation слоя: MVVM или MVI. MVP уже никто не воспринимает всерьез. Расклад такой: с MVVM проще онбординг новых сотрудников, и она лучше по памяти когда дохера событий на экране, но она хуже когда много асинхронщины. MVI сложнее в онбординге, и создается новый State на любой чих, зато один единый State и вы забываете что такое Race Condition. Бум, все, идите к начальству и просите зарплату архитектора.
Я же вам не рассказывал одну прикольную вещь, я уже как пару месяцев провожу алгоритмические собесы у нас в компании. Система конечно потешная, почему-то алгоритмы есть у фронтов и бэков, но нет у мобильных разрабов. Я до сих пор не могу понять логики. Ну допустим, в бэке и правда есть команды, где алгоритмическое мышление крайне важно, а в мобилке и фронте этого меньше. Тогда почему и фронтов гоняют по этим собесам, типо во фронте больше алгоритмов чем в мобилке? Много вопросов...

Я вообще не фанат этой секции, я сам не раз проходил собесы в яндекс, без подготовки и довольно часто их благополучно проебывал. Про это у меня вообще есть всратые истории, я обязательно про них расскажу) Ну так вот, пошел я проводить эту секцию по нескольким причинам, охото было понять как там на другой стороне. Плюс я подустал от обычных android собесов, где одни и те же вопросы из раза в раз. Ну и последняя причина, слегка альтруистичная, я пытаюсь вытянуть всех кандидатов насколько я могу в рамках "закона".

Короч, я решил сделать мини пост с советами, как уменьшить вероятность проебаться на данной секции, если вдруг вы на ней очутились, погнали.

Совет 1. Начинай блять с тест кейсов! Довольно часто, кандидат прочитав задание, и посмотрев приведённый пример, сразу начинает писать код. В середине решение оказывается, что куча всего не учтено и решение превращается в спагетти. Потратьте первые 5 минут на обдумывание, какие могут быть входные данные. Вы так точно поймете ту ли задачу вы собрались решать и у вас будут сразу все кейсы.

Совет 2. Все почему-то забывают про функцию max и min. И дело не в том, что их начинают делать вручную или через if, а то, что довольно часто, задачи в который достаточно правильно вызывать функцию max, начинают городить какие-то сложные условия с кучей boolean и т.д. Не забывайте про min и max и не бойтесь использовать константы для бесконечности.

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

Совет 4. Не забывайте о числах. Мы все работаем с ООП языком, он нас приучает мыслить объектами, аля вот тут товар, вот тут корзина и все в таком духе. Однако в алгоритмических задачах гораздо важнее все представлять в более простых числовых абстракциях. Понимаю совет немного не конкретный, но я хз как это сформулировать. Мы привыкаем писать чистый код, делать кучу boolean для описания условий, однако их часто можно заменить на простую математику из 6 класса, и это сделает задачу гораздо проще.

Понятное дело, чтобы вообще чувствовать себя уверенно на этих собесах нужно решить штук 100 для Российского рынка и штук 400-500 для фейсбуков и всех остальных. Ну и не забывайте, что любой такой собес это лотерея. Вы можете попасть на такого как я, который постарается сделать так, чтобы вы прошли, а можете наткнуться на лютого душнилу, который будет молчать весь собес, или доебеться до форматирования (это блять реальная история). Тут хз, прокачивайте удачу, ну вы поняли...
Интересное наблюдение, я на прошлой неделе сделал пост про критику статей про архитектуру. Что в этих статьях нихера нового, и не понятно зачем они вообще делаются. Запомните этот момент. Также я иногда смотрю статистику по постам, не знаю зачем, мне эта информация нихера не дает, но просто люблю как циферки растут. И вот на обычный пост у меня, 15-20 репостов, а на вот этот пост про архитектуру 80! 80 КАРЛ! Блять, ну не удивительно что статьи на эту тему делаются, видимо это вообще имба тема, чтобы набрать просмотры. Мб канал переименовать в architecture_easy_notes?
Я недавно писал о том, что я давно не читаю статей по мобильной разработке. На самом деле такая же тема у меня и с докладами. Когда был молодым я их смотрел десятками, все было в новинку и интересно. Сейчас я смотрю их крайне редко, в основном это доклады крутых олдов вроде Боиштяна.

Это все что касается именно технических докладов. Однако чем опытнее я становлюсь, тем меня почему-то больше привлекают доклады про жизнь. Потому как разобраться в какой-то технологии ты точно сможешь и без доклада, а вот разобраться в себе, это оказывается гораздо сложнее. У меня большинство людей из окружения ITшники, внезапно. И я вижу проблему, что мы порой слишком увлекаемся работой и забиваем на все остальные сферы жизни типа: здоровья, отношений, хобби. Поэтому в эту тему у меня есть целых 2, must have доклада, именно про жизнь, которые как мне кажется будет дико полезно посмотреть каждому:

👉 Один из самых крутых докладов который я видел в принципе. Это наверное даже больше стендап, нежели доклад. У меня есть близкий друг, который пересматривает этот видос раз в год. На самом деле если вы в сфере IT больше пяти лет, я бы советовал прям сейчас его включить.
👉 Второй доклад примерно про ту же тему с советами по здоровью, эффективность и про то что после 30 оказывается не финишь) В нем кстати есть очень крутой совет про оценку сроков.
Давно я не делал технических постов. Вы наверное совсем заскучали без них, тем более telegram выпустил подсветку синтаксиса, как раз затестим.

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

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

Одна из таких концепций это частичное применение функции. В kotlin конечно такое выглядит не очень удобно как в python или clojure, но все же.

Представьте, у вас есть функция в которую нужно передать 2 аргумента. И вы знаете что меняется только 1-й аргумент, а второй статичный. Что-то вроде такой функции:

fun doSmth(first: String, second: Int) {
// функция делает что-то невероятное
}

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

Все крайне просто, делаем вот такую функцию:

fun <I1, I2, O> partition(
func: (I1, I2) -> O,
arg1: I2
): (I1) -> O {
return { input -> func(input, arg1) }
}

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

И далее передаем нашу исходную функцию и второй неменяющийся аргумент и на выходе получаем функцию в которую достаточно передать уже один аргумент:

fun main() {
val doSmthNew = partition(::doSmth, 42)
doSmthNew("name")
}


Зачем это нужно спросите вы? А я хрен его знает где применить такое именно на kotlin. Однако, как концепция эта штука очень похоже на то, как сделан механизм мемоизации в Compose. Ну и еще я недавно писал скрипт на python, там функция partition в стандартной либе и зашла на ура.
Я пропал на две недели, потому что у меня началась ноябрьская депрессия. Депрессия вызванная необходимостью найти новую квартиру в Питере. Появилась эта необходимость из-за арендодателя, который решил выселить меня в лучших традициях крупных компаний – без объяснения причины. 

И толи мне везло в предыдущие года, толи рынок и правда ебанулся на фоне повышения курса и ставки, но цены на нормальные квартиры неожиданно улетели в космос. Ну да ладно, разумеется я бы не стал делать пост, в котором я только жалуюсь на рынок недвижимости, я буду жаловаться и на либы от гугла.

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

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

И вот взять Paging Library. Вот смотришь на API и документацию и думаешь, ну ведь круто сделали! Довольно удобно, просто, можно читать из БД и из сети, все про красоте прям. Даже учли мега редкие кейсы вроде пагинации в верх и вниз. Вероятнее всего это нигде кроме Твиттера не понадобится, тем не менее. 

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

Дефолтная вроде бы задача, но для Paging Library это настоящий Big Deal. API либы не позволяет это сделать на уровне логики, обновить данные может только пользователь. Другими словами, из UI нужно дернуть специальный метод, чтобы список обновился. Если ты хочешь обновить данные сам, то нужно отправлять событие на UI, чтобы из UI дернуть этот метод. Это какой-то абсурд, они же сами дают рекомендацию по разделению приложения на слои, но вынуждают делать вот такие приколы.

Если заглянуть внутрь, то там прям кладезь крутых примеров как делать не стоит. Как часто у вас возникает идея запихать Flow, в data класс и отправить куда-то? Создатели либы в этом не видят ничего дурного. И вот я думаю, толи я тупой, чтобы понять грандиозный замысел, толи они херней страдают…
🤦‍♂️ История увольнения из-за которой мне стыдно

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

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

Рассорившись с адекватностью и здравым смыслом мы творили на собесах лютую дичь, иногда могли и попросить типа решить простую задачку с leetcode. Молодеж хуле… 

Однажды, пришел к нам в контору кореш нашего коллеги, тоже студент, как и мы на тот момент. Мы провели наш кринжовый собес, он нам понравился (на самом деле нет, ведь мы были зазнавшимися мудаками). Далее он начал вливаться в работу. 
И вот сейчас то я понимаю, что разные люди вливаются по разному, кто-то супер быстро, кому-то нужно чуть больше времени и это норм. Однако мы всегда всех судили по себе, аля если он вливается не так быстро как мы, значит он не правильный программист. 

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

Того разработчика зовут Юра. Юра если ты меня читаешь, прости нас, мы все просрали)))
В начале не понятно зачем это нужно, затем кажется что ты шаришь и все очень удобно, а после ты ловишь себя на мысли, что понятно абсолютно нихуя и кажется, что вокруг все ебанулись. Именно так выглядят стадии изучения gradle. 

На всех проектах рано или поздно нужно сделать какой-то скрипт, который бы автоматизировал какую-то рутину. Что-то вроде генерации отчета, отправки сообщения в рабочий чат, отправки apk куда-либо. Как чаще всего такие задачи делаются на мобильных проектах? Правильно, фиганем сейчас gradle plugin и все будет работать. Код вот тут рядом и язык один и тот же,  все смогут это поддерживать. Поддерживать как сам плагин, так и морально тех кто с ним работает.

Сейчас, работая уже почти год в инфре, я понял это крайне шаткая дорожка. Как только проект вырастет, а он вырастет, вы сильно пожалеете о том, что не захотели потратить время на тот же python. Представьте, у вас простая задача, но каждый раз на CI, вам нужно сначала подождать пока gradle придет в себя, затем сконфигурируется, и только потом запустится. Помимо этого еще и при следующем обновлении окажется, что вы как-то не так эту таску вызываете и у вас начнет все падать. Желая сократить время, вы начали зависеть от системы, которую не контролируете, не говоря уже о ресурсах.

Как тут быть? Все очень просто, если для вашей задачи не нужно знать о графе зависимостей, забейте и делайте CLI. Просто берете python и тупо располагаете скрипты рядом с вашим кодом. Все в одном месте, как и с gradle. Но теперь вы не зависимы от системы сборки, не тратите время на инициализацию графа и разговоры с психологом. Все очень легко дебажить, и вам плевать на обновления gradle и т.д 

Ну а если у вас есть уже какая-то инфра внутри компании, и есть возможность запуливать докер образы или какой-нибудь s3 чтобы туда складывать бинари, то у вас еще и появляется возможность использовать другие языки типа go или тот же kotlin.  

Можно даже пойти дальше и упарится как это сделали разработчики detekt. Вы заглядывали в их репу? Это высший пилотаж как по мне. Возможно я вас удивлю, но detekt можно запускать без gradle как обычную CLI программу. Я вообще планирую на рабочем проекте это внедрить, чтобы порезать время на конфигурацию и вены себе в случае, если gradle не уйдет с рынка.

Короче, что делают разрабы detekt. Они сделали CLI, который можно легко тестировать, дебажить и вносить изменения. Затем они просто делают gradle plugin, в котором есть зависимость на CLI и при запуске gradle task тупо запускает CLI под капотом. Ну не круто ли а? 

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

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

продолжение в комментах 👇
Мне кажется крайне крутой идея выпустить пост прям 31 декабря, посреди новогодней суеты когда его вероятнее всего прочитает никто. Но если вы читали предыдущий пост, сами знаете с кем, имеете дело)

Один из самых крутых сериалов которые я смотрел за этот год, это сериал "Разочарование" от нетфликса. В целом, название сериала полностью совпадает с моим мнением про этот уходящий год. Не то чтобы этот год был прям ужасным, но под конец года я знатно выгорел. Выгорел не от работы, а скорее от всего в совокупности: от проблем в отношениях, от вынужденного поиска квартиры, от того, что работа не драйвит так как раньше, и что я хотел бы, чтоб мои посты выходили почаще (представьте: настал рассвет, пока вы ходили по чаще) Да же сейчас, пока пишу этот пост слова даются крайне тяжко(

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

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

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

Начало года часто связано с планированием и постановкой целей. Поэтому я решил начать этот год с вопроса к вам. А вы ставите себе какие-то карьере цели на год? Я не про OKR сейчас спрашиваю, а вот конкретно личные. Что-то вроде сменить эту галеру на другую галеру по моднее, или вырасти из сеньора в сеньора+?

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

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

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

Парадокс вот в чем. С одной стороны без целей мы будем заниматься херней, я этом профи уж поверьте. Без четких целей нет фокуса, а без фокуса мы отвлекаемся на дичь вроде – срочно переписать весь проект на compose. С другой мы не можем обладать всегда полной информацией и в процессе может выясниться, что мы вообще идем не туда. Но цель у нас как бы поставлена, а поэтому идти к ней все равно нужно. Да и тот же SMART это очень хорошо, только в случае когда известно, как цель достигать. Короче сложно и каждый выбирает стратегию для себя.

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

Причем я не понимаю зачем они это делают? Ведь не ты же его делал, я не до твоего продукта добываюсь, у тебя же жизнь станет лучше если мы будем вместе эту критику доносить до разрабов gradle. Помимо этого, от критики рождаются новые решения, чем сильнее индустрия будет ныть про то, что gradle кусок говна, тем быстрее появится другое решение. Я готов поставить на кон гетеросексуальность разработчиков gradle, что при появлении конкуренции среди систем сборки, они начнут улучшаться более быстрыми тэмпами, перенимая друг у друга хорошие концепции. 

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

Пугает еще то, что чем дольше мы все сидим на gradle, тем дольше с него не слезем. То же самое получилось с linux. У последнего есть куча проблем, но вы в современном мире можете себе представить чтобы кто-то накидал новое ядро операционки с новыми концепциями? Это уже нереально, там написано уже так много кода, что никто не сможет сделать что-то хотя бы частично конкурирующее с linux. Такая же ситуация и с chomium и android.

Ну и что же с этим делать спросите вы? Ну как мне кажется если все хотя бы попробуют собрать проект на других системах сборки типа bazel уже может что-то сдвинуться. Или станет хуже, хрен знает я плохо будущее предсказываю)))
Я как вчера помню свой первый МР (мерж реквест) на проекте с командой больше 1-го разработчика. То что сделали с моим МРом можно смело выкладывать в оранжевый ютуб. Мне тогда накидали 40 комментариев за 5 минут. На проекте работали крайне педантичные разработчики, которые докапывались до каждой строчки кода. Разумеется работая в такой компании, ты рано или поздно сам становишься таким же педантичным фанатиком. Я мог докопаться до чего угодно, до форматирования, до названия переменных, до прически автора. 

Продолжалось это до тех пор, пока на очередном ревью не задал себе вопрос: “а не херней ли я страдаю?”. В ответ на вопрос мне явилось ведение в виде Линуса Торвальдса который сказал мне, что даже для него это слишком. И после этого я понял две вещи: что стоит завязывать работать под грибами, а также нужно пересмотреть свое отношение к ревью кода. 

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

И я сформулировал для себя несколько основных правил, как правильно делать код ревью. В основе этих правил простой принцип: “Не доебывайся до мелочей”.  Все крайне просто, комментирую я код только в 3-х случаях. 

1️⃣ Когда вижу что разработчик делает откровенную херню. Не просто, что решение “не самое лучше”, или что “можно сделать красивее”, а вот прям нельзя. Ебанет если так сделать, и я могу четко с пруфами объяснить почему. 

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

3️⃣ Четкое нарушение конвенций, которые приняла вся команда. При возникновении спорного момента или если такого нет в конвенциях, то сначала выносим на обсуждение и только потом можем докапываться в МР. Если же у вас нет принятых конвенций в команде, тогда на основе чего вы решили доебаться? На основе своих ощущений прекрасного?

Все вот эти вещи вроде: “можно сделать короче“, “в будущем возможно понадобится X, давай переделам”, “так нельзя писать код” идут лесом. Туда же идут всякие идеи по микрооптимизации некритичного кода. 

Мне рассказывали забавные истории про тимлида который оставлял комментарии типа: “Ыыы исправь!” и это блять не шутка. Не можешь четко сформулировать что не так – сиди, блять, помалкивай или иди учиться формулировать свои мысли.
В дополнение к предыдущему, сильная педантичность к проверке изменений приводит к другой проблеме. Большие изменения ревьются крайне долго или вообще забивается на ревью. Это конечно отчасти проблема автора МР, но порой никак без больших изменений. Так устроена наша психика, когда привыкаете докапываться до каждой строчки. Потом смотришь на изменения в 1к строчек и твоей мозг думает, ууу это на долго, давай сначала с мелочью разберемся чтобы ничего не отвлекало. Ну а дальше сами понимаете. У нас в команде вообще есть рофл для таких МРв, если он висит несколько дней и без комментариев, мы считаем что МР достаточно "настоялся" и в нем точно нет косяков.

Ну и еще момент, для всех правил есть исключение. Правила которые я описал выше применимы когда у вас зонеркоманд из сеньоров и крепких мидлов. Когда проводим ревью джунов, можно добавить чуть больше духоты, но аккуратно и с объяснением почему нужно делать так, и так.
До чего же я все-таки ненавижу собесы. Каждый раз нервничаешь как перед первым свиданием. Готовишься, вспоминаешь скорости работы всех стандартных структур данных. Вспоминаешь задачки, которые недавно решил на leetcode. В туалет бегаешь несколько раз из-за стресса. Проверяешь что оборудование работает нормально. Справляешься с заплетанием языка в начале собеседования.

Так еще и после фидбэк оставлять, ведь это все со стороны собеседующего...
Итак, после того как я рассказал о себе, наверняка у кого-то мог возникнуть вопрос. Что делать, если я долбаеб и не собираюсь меняться?

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

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

Обесценивай опыт других людей. На собесе вообще не обращай внимания на то, чем занимался разработчик и в чем он крут. Чем более крутую штуку он сделал на прошлой работе, тем больше ты должен доказать ему, что все это гнилая, никому не нужная херня. Спрашивай то, что вообще не влияет на работу (вроде флагов Activity) и которую можно посмотреть в справочнике. Если разработчик не ответил, то сразу ставь ему грейд сильно ниже того, на который он тянет. Путь вообще спасибо скажет, что ты посвятил ему свое время.

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

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

Никакой предсказуемости. Каждый твой поступок должен вызывать дикое удивление у окружающих. Все ждут от тебя взвешенных решений в выборе технологий и адекватности в общении? Удиви их!

Работай по выходным!

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

Выебывайся. Всегда и везде, и всем чем только можно, любым даже самым незначительным достижением. Поправил незначительный баг, сделал статью с 2-мя просмотрами, купил BMW. Исключительно важно, донести это всем, до кого можешь дотянутся.

В этом вся суть, все что делается вокруг исключительно для тебя. Забудь слова “уважение” и “здравый смысл”, это для всяких мудил которые не понимают твоего величия.
⚖️ Когда нужно использовать статику

Недавно ко мне прилетел вопрос, касательно того как правильно делать логирование. Нужно ли делать логер статичным или же инжектить его везде через DI?

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

И вот топ 3 вещей которые обязаны делаться через статику:

📜Логирование/Аналитика. Мне досталось одна либа, в которой логирование было сделано именно через DI. Каждый раз когда мне нужно было писать лог, приходись прикидывать логер через конструктор, это максимальное неудобное убожество. 

Суть логера в том, что он должен быть доступен в любой части программы, независимо от слоя UI/Presenter/Domain. Может возникнуть вопрос, а как тогда быть, если логер нужно подменить, например заменить в релизной сборке. Идем и смотрим как это сделано в Timber. Либа предоставляет возможность подменить реализацию во время инициализации приложения через статические методы. Устанавливаете нужный логер вначале и потом не парите голову. 

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

🖼 Загрузка картинок. Вот это вообще такая вещь на грани, вот почему. Очевидно что смешивать View и DI затея не самая удачная. Потому как у вас View становятся зависимы от вашего DI, помимо этого важно с самим DI не закосячить в плане скоупов и ЖЦ View, так еще это и максимально неудобно в коде. 

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

Тут на самом деле, даже и думать не придется, потому как все либы для работы с картинками работают по одному и тому же принципу. Для примера можно взять coil. По умолчанию используется один и тот же экземпляр загрузчика, который можно сконфигурировать при старте приложения. Если же нужен другой загрузчик, можно прям на месте загрузки сконфигурировать свой и подсунуть в туже же самую функцию.

Dispatchers/Schedulers. Раньше почти на каждом проекте был следующий подход. Мы не используем библиотечные шедулеры (вроде Schedulers.io(), Schedulers.computation()) а сделаем интерфейс:

interface Schedulers{
fun io():Schedulers

fun computation():Schedulers
}


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

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

Ну а что делать если подменять все таки нужно? Если RX, то ничего делать не нужно, он из коробки позволяет подменять стандартные шедулеры. Корутины к сожалению такого не умеют, однако  это можно сделать через статику. Делаем класс, который по умолчанию возвращает библиотечные реализации диспетчеров, а в тестах эту статику меняем. Единственный минус, что важно теперь следить чтобы все использовали этот самый класс для получения диспетчеров, который мы договорились использовать.
2025/07/07 21:56:05
Back to Top
HTML Embed Code: