Dev Easy Notes
3.17K subscribers
123 photos
1 video
147 links
Работаю в IT уже 8 лет. Рассказываю про разработку простым языком. Полезность скрыта под тупыми шутками и слоем мата. Лучший underground канал про разработку, который вы сможете найти.

По сотрудничеству писать @haroncode
Download Telegram
Так как я стал уже гуру CLI, в голову мне пришла идея, а не оформить ли список best practice по этой теме. Да в канале про android разработку! Ну а чего, все вы рано или поздно станете, или лидами, или тех лидами так или иначе, вам придется сделать парочку задач связанных с инфраструктурой.

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

👉 Не делайте CLI на java. JVM для сервера – круто, JVM для мобилки – сомнительно, но окэй, вроде работает, JVM для CLI – проклятие. Часто jar получается огромный, плюс сама jvm весит нефигово и жрет дохера ресурсов. В итоге ты это чудо не добавишь в докер образ, ибо последний разбухнет до невероятных размеров. Делайте CLI на java только в том случае, если у вас есть либа на java и вообще нет никаких других вариантов.

👉 Какой язык использовать? Если не важно как быстро должен работать скрипт берите Python, важно чтобы работал быстро – Go, если нужно еще и системные вызовы использовать и супер перфоманс – Rust. Держите в голове что в 99% случаев скорость работы будет ограничена сетью, а не CPU, поэтому берите Python и не выебывайтесь.

👉 Если не читали про unix way, то перед разработкой CLI тулзы идите и почитайте. Кратко – лучше делать несколько CLI которые хорошо делают что-то одно, чем одну CLI, которая делает все. Даже если она это делает хорошо. Атомарные CLI можно связать вместе через pipe и вообще запускать как угодно, это дает гибкость и избавит от гемора в будущем. Наверное...

👉 Не пишите обработку аргументов сами. Совет скорее для совсем начинающих, тем не менее. Охренеете это делать вручную, всегда сначала погуглите инструменты для вашего языка. Для примера, в python из коробки есть ArgumentParser который позволяет это делать в две строки.

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

👉 Не завязывайтесь на окружение. У нас есть внутренний инструмент, который завязывается на переменную окружения CI. Другими словами, работает эта CLI только на CI, и чтобы протестировать ее локально, нужно делать приседания с переменными окружения. Не делайте так, всегда должна быть возможность протестировать CLI локально.

👉 В дополнение к предыдущему. Если вы хотите чтобы прога получала данные из переменных окружения, добавьте возможность указывать их явно через аргументы. Чтобы было так: если в аргументах не указано берем из окружения, если указано берем из аргументов.

👉 Про ключи писал в прошлом посте, но напомню, длинные версии на CI, короткие локально.

👉 Для всех CLI есть один негласный контракт, если много ключей, то их можно записать в файл, а вызывать CLI следующим образом: ./program @path_to_file. Таким образом можно ключи, которые меняются редко вынести в файл и сделать вызов лаконичнее.

👉 Gradle или CLI? Это тянет на отдельный пост, но давайте так. Сначала ответьте на эти вопросы: Вам нужно знать про граф зависимостей? Вам нужно как-то использовать сторонний gradle plugin? Если на один из этих вопросов вы ответили четкое "Да", делайте задачу через gradle плагин, если же сомневайтесь, лучше сделайте скрипт на python. Поверьте так будет быстрее как в разработке скрипта, дебажить gradle плагин это то еще удовольствие, так и в производительности, python скрипт в отличие от gradle не тратит время на конфигурацию или скачиванию самого себя.
👍431👎1
Ну что ребятишки, пришло время для откровенного разговора, садитесь в круг. В прошлом году я делал один такой backstage пост, больше про некоторую рефлексию, нежели про технологию. Я пишу этот пост отчасти для того, чтобы вы не подумали что я куда-то пропал, хотя это не далеко от правды. Скорее просто набор мыслей касательно канала. И да выкладываю его прям вечером, че вы мне сделаете я в другом городе!

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

Помимо этого я начал замечать в себе зачатки самоцензурирования. Это нельзя сказать – я тиммейтов оскорблю, это нельзя сказать – ведь меня сразу засмеют, это нельзя – тимлид читает меня часто, а это нельзя сказать – это небезопасно🕊️. Это к тому что я немного завидую тому же Филу из "Мы обречены", который вообще в космос улетает в своих высказываниях на ракете похуизма. У меня пока так не получается, хотя это бы сделало контент более острым что-ли, все таки я позиционирую этот канал как underground.

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

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

Что будет дальше? Сфера моих интересов просто сдвигается с углубленного погружения в Android на разработку под мобилки в целом. Это не значит, что теперь про Android я ничего писать не буду, это значит, что конкретно про Android и библиотеки для Android постов будет меньше, а больше будет про подходы, инженерные практики и computer science.
👍11226🔥6👎2
Теперь вернемся к набросам на пост про CLI. Самый интересный коммент был про то, что docker с jar можно сделать мелким и вообще jdk образы довольно минималистичные. Я пошел в docker, не поленился и скачал три образа: jdk, go и python. Скачал самые дефолтные образы, я не стал погружаться в то, на чем они основаны, вероятнее на каком-нибудь дистрибьюторе вроде ubuntu, который помимо нужных вещей, тянет за собой еще кучу всякого дерьма.

Оказалось что да, jdk самый минималистичный образ из всей троицы, тут вы меня уели ничего не скажешь: jdk – 500mb, python – 875mb, go – 850mb. Однако, и у go и у python есть alpine версия образа, т.е образ базирующийся на легковесном дистрибутиве, чтобы точно не тащить ничего лишнего. И вот тут уже go и python весят по 100mb от силы. Официальной alpine версии образа для jdk нет, так же как и нет jre версии (начиная с 11 java) в которой был бы только runtime – увы и ах.

Разумеется можно сделать свой образ, в котором не будет ничего лишнего, но вы точно уверены, что сделаете все правильно и готовы потратить на это силы? То же самое можно сказать про оперативку и ресурсы. Конечно можно оптимизировать java по памяти, но и блоху подковать можно, вопрос в том, нужно ли на это силы тратить?

Помимо этого, я все же говорю про CLI в рамках работы на CI, причем речь идет о CI для мобилок. Вот тут вообще начинаются преколы, когда узнаешь что на iOS Job гоняются не на виртуалках, а на реальных конкретных apple устройствах. И не факт, что там вообще jre есть, а вот python там будет 100%. Ну тут еще есть фактор, что когда iOS разработчики слышат сочетание букв JVM у них пена из рта начинает идти.

Касательно косяков с либами в CLI написанном на python это да, больновато. Тут go и правда выглядит более привлекательным, если CLI будет запускаться на разных устройствах у клиентов. Однако если CLI будет запускаться только на CI как часть какой-то автоматизации, то тут вы полностью контролируете все пакеты через docker образ, тем самым нивелируя эту проблему.
👍161😁1
Хочу рассказать еще одну наболевшую вещь про Gradle, про которую почему-то не принято говорить. В Gradle максимально ебанутая система логирования.

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

Если кто-то пробовал разрабатывать плагин, то должен знать что gradle в каждой таске позволяет получить логер. В gradle используется интерфейс slf4j для логирования. И казалось бы, раз это slf4j который славится возможностью подсунуть свою реализацию, то писать лог можно куда угодно, да? Пизда! Gradle позволяет писать лог только в консоль, хочешь лог в файл перенаправляй поток.

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

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

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

В тему про это есть отличный доклад где разраб из Яндекса рассказывается как они избавились от всех дебажных логах у себя на бэке, и предпочли другие системы для мониторинга. В кратце, стоит всегда задумываться для чего тебе нужен конкретный лог, в каких ситуациях он тебе понадобится, и если ответ "На всякий случай", этот лог тебе не нужен!
👍27🔥6
У меня есть друг с которым мы в былые времена, когда были начинающими мидлами горели тем, чтобы сделать какой-нибудь крутой pet или open source проект. Как и подобает мидлам мы страдали страшным перфекционизмом касательно автоматизаций. Сейчас вспоминать это смешно, но тогда это казалось невероятно важным.

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

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

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

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

Как я делаю сейчас при подобной разрабоке, которой к слову очень мало сейчас у меня. Я кладу болт на всю автоматизацию, делаю самый минимум насколько это возможно: CI – только сборка на МР, все остальное лесом, автоматическая отправка в Maven – либо руками, либо с готовым плагином без кастомной разрабоки, тесты – смотри мой пост про тесты выше, код ревью – только самый минимум по архитектуре. Даже несмотря на это далеко не всегда хватает энергии, чего уж говорить про автоматизации выше.
👍52🔥95
У меня на кухне, как у многих, стоит Алиса. Как голосовой помощник она естественно используется только для двух вещей: включить нужную мне музыку или засечь таймер. Мне нужные только две эти функции, ничего более. Однако последнее время, каждый раз, попросив, засечь таймер, она также начинает мне предлагать либо подкаст, либо книгу, либо оформить "супер выгодную" подписку.

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

Современное программное обеспечение, дохера на себя берет, вместо того, чтобы беспрекословно и молча выполнять поставленные задачи. Это все большая подводка, чтобы да, опять пожаловаться на Gradle, а точнее на разработчиков agp.

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

Почему так? Да потому что agp, который использует под капотом jacoco, решил что ему виднее какой код нужно модифицировать для сбора Coverage, а какой нет. Как я только не пытался заставить его модифицировать код тестов, все четно.

Вот в чем причина, Jacoco изначально был как сторонний плагин, если хочешь собирать Coverage, подключаешь его, настраиваешь как тебе нужно и он работает. Однако разработчики agp решили нам "упростить" жизнь и запихали работу с jacoco к себе внутрь и теперь как бы сами конфигурируют его как нужно. Для типичного флоу хватает более чем, но как только ты пытаешься отойти от базового использования – пожалуйте нахуй.

И вот казалось бы, ну нахера, нахера они полезли куда их не просят? Я сам разберусь как мне нужно настроить JaСoСo, чтобы он вызывался как нужно мне, а не как нафантазировали себе разрабы agp. У Gradle есть система Input Output для Task, которую они (gradle) сейчас очень активно форсят и это круто. Мне кажется каждый плагин, каждая Task в Gradle так и должна работать. Вот я что-то ей даю на вход, и вот я что-то ожидаю на выходе. В какой момент Gradle вызовет эту таску пофиг, пусть сам разбирается, мне важен только результат.

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

Если вы делаете решения для разрабов, то делайте инструменты, которые делают что-то одно хорошо. Не пытайтесь сделать инструмент который дофига на себя берет. Хороший пример либы Вортона, у него в первой версии же тоже все под капотом само конфигурировалось и даже была завязка на Gson. Однако Жека то умный, он сразу понял что это путь в никуда и теперь у того же Retrofit куча настроек на входе. И что имеем теперь? Либы Вортона использует вся индустрия, потому что они не делают ничего лишнего, а что нужно делают настолько хорошо насколько возможно.
21👍9🔥4😁3👎2
А все тут страдают синдромом самозванца? Или вы себя считаете недостаточно прокаченными, чтобы считать, что у вас синдром самозванца? Я сам частенько ловлю это ощущение, когда читаю какую-нибудь крутую статью или смотрю доклад крутых ребят. Возникает ощущение, что они все поголовно гиганты мысли, гуру программирования, а я тут такой название функции не могу 20 минут придумать. Или вот у меня друг есть, который никак не может уйти со своей галеры, потому что считает себя недостойным компании получше. Разумеется все попытки его переубедить тщетны.

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

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

NDK, C/С++. Очень базово, что-то делал в универе, но не сложнее связного списка. Когда вижу код на плюсах почему-то хочется убежать. Не ну вы видели вообще код на плюсах, он же даже выглядит пугающе.

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

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

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

Все что касается камеры. За всю карьеру ничего не приходилось делать с камерой, все ограничивалось отправкой Intent, а дальше пусть юзер сам как-то там что-то сфоткает.

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

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

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

Мультиплатформа. Казалось бы, нам android разработчикам крайне легко вкатится в это. Уже даже Compose без пяти минут как будет мультиплатфомерменным. Но чет как-то впалду с этим возится в свободное время, чтобы понять эти actual, expect и фризы, хотя вроде последние уже не нужны и они переписали мемори модель. Короче я перестал следить за новостями на этапе, где корутины вот-вот должны были сделаться многопоточными на iOS. Ну и во Flutter я только запускал Hello World. Просто после kotlin тяжело воспринимать язык, где есть ключевое слово new.
👍9721🔥9😁5
И все перечисленное выше касается только мобилки, а сколько всего я не знаю если говорить про фронтенд и бэкенд, даже подумать страшно)
👍377
Давненько не делал постов, правда в этот раз по уважительной причине. Вы не поверите, но меня очень сильно увлек compose, видимо я соскучился по UI работая в платформенной команде.

Есть у меня сторонний пет проектик, и в нем одной из кор фичей это функционал с тиндоровскими карточками. Это не приложение для дейтинга, ну, пока что... И вот значится, решил я сделать такие карточки на Compose, он же позиционируется как супер просто фреймворк для UI. Историю про то, как я делал эти карточки, зачем и почему не взял готовые, я сделаю отдельным постом, после того как выложу реализацию на github. Пока лишь напишу вывод, нихера он не простой этот ваш Compose.

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

Что я подразумеваю под сложными вещами? Это те штуки, которые выходят за рамки типичных кейсов: для gradle это будет работа с плагином jacoco как нужно мне, для корутин это сложные операторы с параллельными стримами, которые были в RxJava, но их нет во flow, для compose это кастомные ленивые списки, которые жуть какие сложные по сравнению с RecyclerView.

Тенденция у нас следующая, уровень задач, которые мы делаем каждый день остается прежним, однако порог вхождения в эти задачи становится ниже. В 90% случаев мы пилим приложения, которые отправляют какие-то запросы на бэк и рисуют какой-то UI. Если раньше нужно было посвятить концепции RxJava какое-то время, чтобы делать запросы нормально, то сейчас для обычных запросов особо не нужно напрягаться, корутины за вас все это сделают. Если раньше для кастомных UI нужно было погружаться в устройство работы View, то с Compose это в 90% не нужно и все можно сделать из стандартных компонентов. Ну и Gradle, разработчики AGP делают все, чтобы начинающим вообще не приходилось разбираться для решения задачи, главное повторить как сделано в доке.

Хорошо это или плохо? На самом деле я не знаю, возможно и в стародавние времена кто-то говорил что-то подобное про верхнеуровневые языки программирования, когда все писали на ассемблере. Удручает только факт того, что API становится проще, однако за это мы платим производительностью. Если насчет корутин и RxJava еще можно поспорить что из них лучше, то Compose пока все еще проигрывает View. Оно и понятно View оптимизировали 10 лет, а Compose в релизе без году неделя. Про Gradle я вообще молчу, для большого проекта кажется уже нужно будет сервер домой покупать.

В детстве у меня был комп с 512 mb ОЗУ под Windows XP, на котором я мог запустить GTA Vice City и еще кучу всего. Сегодня же мы имеем то, что Android 13 требует минимум 2GB ОЗУ. Минимум блять, т.е он скорее всего еще и зависать при этом будет. И вот начинаешь думать, а мы точно с этими удобными фреймворками в нужную сторону двигаемся?
👍46🔥11🤔9
Перечитал пост и понял что немного размазана получилась главная идея. Суть такая – простые задачи стало делать еще проще, сложные задачи стало делать сложнее, потому как нужно разбиратся в устройстве фреймворков, которые предоставляют удобный API, но становятся переусложнеными внутри. И при всем при этом мы еще и в производительности проседаем.
👍46👎1
Когда я начинал учить программирование, мне было не особо понятно, что это за возня со всякими переменными окружения типа JAVA_HOME. Я же скачал JDK, пусть она сама настроит себя как нужно. Тем более, idea же умеет сама билдить и запускать проекты, зачем еще нужны какие-то системы сборки и что это вообще такое?

Потом чуть повзрослев ты понимаешь, что хорошему бы не завязываться на конкретную IDE. Другие разрабы могут использовать что-то кроме idea(хотя для java проектов это странно, но такие бывают), или использовать разные версии которые будут конфликтовать, много гемора крч.

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

После, обретя уже какой-то опыт, научившись работать с системами сборки, jdk я всегда использовал тот, который идет вместе с IDE. И в этом случае у нас тоже получается зависимость от IDE, фиг знает может есть JDK быстрее и стабильнее? В этот момент тебя озаряет, а так вот зачем это мозгоебство с JAVA_HOME.

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

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

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

Да Android Studio охренительно удобная, правда все эти крутые миграции заложенные в нее больше похоже на попытки залатать архитектурные проебы в AGP, тем не менее, она умеет много чего, что еще не умеют другие IDE. И несмотря на это, чем старше становишься, тем больше пытаешься не то, чтобы отказаться от IDE и пересесть на VIM, а скорее диверсифицировать инструменты. Чтобы отказ в одной тулзе не блокировал твою работу, а для этого стоит хотя бы минимально разобраться как работают системы сборки, как студия запускает тесты и как это можно было бы использовать без студии.

Я периодически балуюсь с GO, и когда ты уже в своей экосистеме все поделал вручную, без помощи IDE, оказывается что поработать с другой экосистемой становится дико просто, ведь концептуально используются одни и те же подходы для зависимостей, билда и т.д
👍46🤔6🔥5😁21
У меня есть pet проект, и одной из кор фичей в которой это тиндоровские карточки. Сами карточки сделала моя подруга, я присоединился к этому проекту позже. Сделала она карточки достаточно круто: отзывчивая анимация, работает все плавно, красиво меняются цвета. Однако карточки получились нефига не расширяемые, крайне не удобно со стороны API. Например, сделать несколько типов разных карточек уже тяжело.

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

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

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

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

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

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

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

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

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

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

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

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

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

Первую статью закинули в наш 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. Бум, все, идите к начальству и просите зарплату архитектора.
72🔥30👍18👎4👏4😁1
Я же вам не рассказывал одну прикольную вещь, я уже как пару месяцев провожу алгоритмические собесы у нас в компании. Система конечно потешная, почему-то алгоритмы есть у фронтов и бэков, но нет у мобильных разрабов. Я до сих пор не могу понять логики. Ну допустим, в бэке и правда есть команды, где алгоритмическое мышление крайне важно, а в мобилке и фронте этого меньше. Тогда почему и фронтов гоняют по этим собесам, типо во фронте больше алгоритмов чем в мобилке? Много вопросов...

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

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

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

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

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

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

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

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

👉 Один из самых крутых докладов который я видел в принципе. Это наверное даже больше стендап, нежели доклад. У меня есть близкий друг, который пересматривает этот видос раз в год. На самом деле если вы в сфере IT больше пяти лет, я бы советовал прям сейчас его включить.
👉 Второй доклад примерно про ту же тему с советами по здоровью, эффективность и про то что после 30 оказывается не финишь) В нем кстати есть очень крутой совет про оценку сроков.
37👍19🔥4👎1
Давно я не делал технических постов. Вы наверное совсем заскучали без них, тем более 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 в стандартной либе и зашла на ура.
👍33👏21
Я пропал на две недели, потому что у меня началась ноябрьская депрессия. Депрессия вызванная необходимостью найти новую квартиру в Питере. Появилась эта необходимость из-за арендодателя, который решил выселить меня в лучших традициях крупных компаний – без объяснения причины. 

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

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

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

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

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

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

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

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

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

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

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

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

Того разработчика зовут Юра. Юра если ты меня читаешь, прости нас, мы все просрали)))
👍42😁40🤯94🔥4👎3🤔2