iOS Makes Me Hate
3.94K subscribers
1.16K photos
167 videos
15 files
1.34K links
Авторский канал про iOS разработку. Путь продуктовых самураев в MAANG.

Самое больше iOS сообщество практиков: https://boosty.to/lionbond/

Автор: @lvbond Senior iOS Yandex, ex-Avito, VK
Download Telegram
📌 ЗАКРЕПЛЯЕМ МАТЕРИАЛ
Вообще у меня уже пару лет стоит пунктик покопать в сторону реверс инжениринга иос. Хочется обвалиться парой книг в будущем и пописать сюда выжимки, но пока читаем статью и думаем, как сделать свой ответ Appstore

https://habr.com/ru/company/dsec/blog/676094/
5💯1
Коллизия хэш-мапы

🟠 lvl: mid+

👆В предыдущих сериях мы узнали о Hashable и для чего он нужен. Сейчас же поговорим о коллизиях хэша.

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

До этого стандарта разработчики страдали частой коллизией, особенно работая с цветами.

ℹ️ Коллизия происходит, когда разные входные данные производят одинаковый хэш, но значения не равны

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

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

Детальнее можно познакомиться отличном материале SE-0206

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

Однако мы можем улучшить её, адаптировав хэш-функцию к своему домену.

- Почитать о производительности Hasher в треде с сеньором-помидором из яблока
- Мощненькое чтиво про приемы хэширования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
Чем отличается настоящий программист от кодера?

В снг (а может не только) почему-то считатается, что настоящий программист — это не только кодер, но и чел, кому можно доверить фичу.

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

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

В книге сразу дается ответ на вопрос "Кто такой настоящий программист?"

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

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

А вы программируете или разрабатываете?

P.S. второй раз пришел к книге. Буду иногда вбрасывать вижимки
👍10😐4👎3
Закон Хайрама по сути это не про обесценивание интерфейса, а про то, что не стоит расчитывать только на него.

Только не стоит прикрывать нежелание написания доки, интерфейса и других вспомогательных штук — большими масштабами команды из 2,5 человека

Кстати, гуглил про закон и наткнулся на прикольный репо

https://solarrust.github.io/hacker-laws/
4👍3
Символьный брекпоинт

🟢 lvl: jun+

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

https://medium.com/swlh/symbolic-breakpoint-xcode-in-2-minutes-5ca86f257b51
❤‍🔥7🥱3
Рубрика "офигенные подгоны".

Смотрите че нашел, целая куча книг просто так бесплатно в гите

Спасибо бэтмену за чистый Готэм 🤡

https://github.com/wuzhouhui/misc
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥8👍2
Яндекс заопенсорсили свой фреймворк для backend-driven ui

https://divkit.tech/
💩10👍1🔥1
Зачем нужны юнит-тесты?

Частое заблуждение, что на мобилке юнит-тесты не нужны. Достаточно лишь е2е и UI.

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

Обычно е2е проходят по самому простому пути:
1. Выполняю флоу
2. Смотрю, есть ли текст, кнопка, вьюха в иерархии вьюх, которые видит пользователь.

А что там под копотом никто не хочет тестировать.

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

Какова же цель юнит-тестирования?

Его цель — обеспечение стабильного роста программного проекта. Ключевым словом здесь является «стабильный». В начале жизни проекта развивать его довольно просто. Намного сложнее поддерживать это
развитие с прошествием времени.

Чем же хороши юнит тесты?

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

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

Ускорение разработки
Ну и понятно, что ручной кейс намного медленней, чем пару сотен миников

Но различия между хорошими и плохими тестами не ограничиваются вкусами. Далее разберемся в отличиях хорошего и плохого теста.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Оценки качества тестов

Существует несколько проверок качества юнит тестов. Первая и самая распространенная — code coverage

⚪️Code Coverage: наиболее часто используемая метрика покрытия, также известная как test coverage. Эта метрика равна отношению количества строк кода, выполняемых по крайней мере одним тестом, к общему количеству строк в основном коде проекта.

🕹Code coverage (test coverage) = Количество выполненных строк кода / Общее количество строк кода


Покрытие в примере (см скрин 1) вычисляется легко. Общее количество строк в методе равно 5.  Количество строк, выполняемых в тесте, равно 4 — тест проходит все строки кода, кроме команды return true. Таким образом, покрытие равно 4/5 = 0,8 = 80 %.

Что будет, если отрефакторить этот метод и убрать избыточную команду if? Посмотрим скрин 2

Изменился ли процент покрытия? Да, изменился. Покрытие кода увеличилось до 100 %. Но улучшилось ли качество тестов с таким рефакторингом? Конечно же, нет. Тест по-прежнему проверяет то же количество ветвлений в коде. Этот простой пример показывает, как легко подтасовать процент покрытия. 

⚠️Процент покрытия служит хорошим негативным признаком, но плохим позитивным.

➡️🔀Branch coverage:

Другая метрика покрытия называется branch coverage (покрытием ветвей).

Branch coverage показывает более точные результаты, чем code coverage. Вместо того чтобы использовать количество строк кода, эта метрика смотрит на if и switch.

Branch coverage = Количество покрытых ветвей / Общее количество ветвей

Чтобы вычислить метрику branch coverage, необходимо подсчитать все возможные ветви (branches) в коде и посмотреть, сколько из них выполняются тестами. Вернемся к предыдущему примеру со строкой.

ℹ️ Метод IsStringLong содержит две ветви: одна для ситуации, в которой длина строкового аргумента превышает пять символов, и другая для строк, длина которых менее или равна 5 символам. Тест покрывает только одну из этих ветвей, поэтому метрика покрытия составляет 1/2 = 0,5 = 50 %.
41
Crash Budget

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

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

Метрика будет учитывать влияние каждого отдельного юнита на Crash-free users и подсвечивать проблемы.

Начальный порог на 1 юнит - 0.0179%
формула = целевой crash-free/число юнитов

Мониторинг работает автоматически + уведомляет юниты в случае привышения бюджета по крешам. В случае игнорирования юниту выдаются санкции.

Crash-free users — процент пользователей, у которых не было крэшей в приложении за выбранный период.

Crash Budget — допустимый процент крэшей у пользователей в расчете на 1 юнит за выбранный период.

Таким образом команда задумывается не просто о написании тестов, как об отчетности. Она сплочена общей проблемой и использует инструменты тестов, как повышение стабильности этих показателей.
👍4🔥1
😡
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
че плюнет в консоль?
Anonymous Quiz
11%
6
10%
1
63%
3
12%
ничего
3%
уйдет в минус
😁4
Property Observers

🟢 lvl: jun

В Swift есть два типа свойств:

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

⚫️ computed properties — выполняют вычисления на основе этого состояния

ℹ️ Когда вы объявляете stored property, у вас есть возможность определить наблюдателей свойств с блоками кода, которые будут выполняться при установке свойства. Наблюдатель willSet запускается до сохранения нового значения, а наблюдатель didSet запускается после. И они выполняются независимо от того, равно ли старое значение новому значению.

Иногда это удобно для валидации поля перед отправкой (рис. 3).

https://nshipster.com/swift-property-observers/
👍7
"Грокаем алгоритмы"

Вода: 0%
Полезность: 4.5 из 5*

Думал ли писать микро-рецензию на most popular книгу про алгоритмы... Кажется каждый, кто начинал разбираться в теме всеми путями выходил на нее. Ютуберы, статьи, коллеги. Ее советует каждый. Особенно фронтендеры, которые с алгоритмами работают реже всего и форма подачи других книг — непривычна

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

Напоминаю, что все книги тут
👍12
Зачем мне нужны юнит тесты?

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

Но есть и минусы:
- в 90% случаев UI тестами покрывается только 1 успешный кейс и забывается про кучу корнеркейсов. Для всех их дорого писать и они будут очень долго выполняться.
- они детектят только факт падения, но не дают причины
- Не знают о деталях работы сервисов, холдеров и тп за рамками UI

В итоге получается, что мы просто экономим на ручном тесте с сообщением "иди посмотри у тебя тест упал".

Как мне помогают юнит тесты? Сейчас я сделал фичу, которая выйдет в релиз в марте 2023 года. За 6 месяцев мне нужно как-то убедиться, что фича не упадет на проде и доедет в рабочем состоянии. Да, UI тесты и мок-данные могут обезопасить и как-то сэкономить время на детект.

Но когда мне придет факт о сломанном проде мне нужно время, чтобы освежить память и найти ответы на вопрос "А что я делал пол года назад и как это должно быть в 9 из 10 других случаях, которые не покрыли UI тесты?".

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

Также они не дадут накопиться снежному кому недоработок, которые будут появляться из-за аффекта зависимых сервисов.
👍8