data будни
1.48K subscribers
120 photos
1 video
2 files
237 links
работаю инженером данных и пишу в основном про это.

Профильные ссылки с коротким резюме (статьи, доклады, подкасты), иногда «софтовое» — например, про поиск работы.
Download Telegram
data будни
😱 ААА! Код-ревью Прошёл тут эпичный код-ревью: 20 комментов в самом пулл-реквесте и ещё 43 сообщения в соответствующем треде в Слаке. Было жёстко, но интересно! Всё началось как приключение на 20 минут: поправить в двух сущностях поля партиционирования и…
Необязательные код-ревью

Интересный подход применяют в компании Raycast — они решили отказаться от обязательных код-ревью и коммитить сразу в дев ветку. Ежедневно автоматика собирает внутренний релиз из этой ветки, чтобы проявить возможные нестыковки.

Приводят следующие доводы:
⁃ Ревью подрывает доверие, типа твоему решению не доверяют и за тобой приходятся проверять код
⁃ Баги случаются и после код-ревью, то есть это не 100% гарантия
⁃ Ревью отнимает время, а значит тормозит разработку

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

https://www.raycast.com/blog/no-code-reviews-by-default

И к заметке есть отдельные комментарии, где радуются за авторов и потом рассказывают почему так делать нельзя, и почему всё сломается.

https://news.ycombinator.com/item?id=27606066

И в комментариях приводят ссылку на ментальную модель про забор Честертона. Мол, не спеши удалять то, что сделано до тебя, пока не разобрался зачем оно нужно. «Не нужно» или «не знаю зачем нужно» — недостаточные аргументы. Если предположить, что делали не полные дураки, то надо для начала разузнать истинную причину зачем делали и уже судить по ней.

https://fs.blog/chestertons-fence/
👍2
data будни
Необязательные код-ревью Интересный подход применяют в компании Raycast — они решили отказаться от обязательных код-ревью и коммитить сразу в дев ветку. Ежедневно автоматика собирает внутренний релиз из этой ветки, чтобы проявить возможные нестыковки. Приводят…
Максимизация скорости разработки через ZDD©

К предыдущему посту Игорь Мосягин прислал релевантную ссылку — как Илья Лебедев 2 года назад внедрял в BestDoctor нечто под названием Zaeb*s Driven Development.

https://youtube.com/watch?v=8lSG028Z2Vg

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

Как было:
1. Фича-бранч у каждого разраба
2. Мерж-реквест, который ревьюился (сколько-то кем-то)
3. Все фичи спринта мерджились в релиз-ветку
4. Всё «регрессилось»
5. Мерж в мастер → прод

Как хочется:
⁃ очень частые интеграции кода
⁃ частые релизы
⁃ много тестов
⁃ автоматизировать что можно
⁃ not break things much

К чему пришли:
⁃ фигачить в мастер, к чёрту бранч
⁃ релизы по расписанию на кроне (неотвратимы как рассвет!)
⁃ тесты не блокируют релиз (хе-хе)
⁃ код-ревью не блокирует релиз (хе-хе-хе!)
⁃ боты говорят людям, что делать (посмотреть такой-то пр до HH:MM сегодня)
⁃ обвешали процесс метриками, которые прорастают в OKR
- по ночам на простаивающем железе гонялись времязатратные тесты

Общие подходы:
⁃ убираем ручной труд
⁃ сокращаем ментальную сложность — что можно перекладываем на машины
- много общаемся с коллегами, объясняя свои подходы =)
👍1
Мета ДВХ: ДВХ для ДВХ

Посмотрел доклад Жени Ермакова двухлетней давности о том как они делали МетаДВХ в Яндекс Такси. Отдельное удовольствие сначала поработать годик внутри, а потом посмотреть такое вводное видео как пришли к такому решению.

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

Мы пользуемся такими отчётами, чтобы отслеживать использование новых объектов (не зря ли мы старались, добавляя их); а ещё поддерживаем счёт в нашей битве за пользователей с «теневым двх»: ключевая метрика здесь — соотношение использования двх-объектов ко всем прочим.

https://youtube.com/watch?v=EHmf0tTxd6A
🔥7
Netflix Chaos Monkey

чтобы достичь доступности в распределённых сервисах используют избыточность: несколько дисков в рейд-массиве вместо одного или несколько машин вместо одной.

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

даже когда есть чёткие инструкции по восстановлению, только практика может отточить навык, а чтобы такая практика происходила регулярно, в Нетфликсе в инфру запускают МАРТЫШКУ ХАОСА (лайк за нейминг!).

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

в конце приходит рейд-босс — Chaos Gorilla — и вырубает целую зону в облачной инфре.

https://netflixtechblog.com/the-netflix-simian-army-16e57fbab116
🔥16
data будни
Мета ДВХ: ДВХ для ДВХ Посмотрел доклад Жени Ермакова двухлетней давности о том как они делали МетаДВХ в Яндекс Такси. Отдельное удовольствие сначала поработать годик внутри, а потом посмотреть такое вводное видео как пришли к такому решению. Суть доклада…
DWH → Data Mesh

Рассказ Жени Ермакова как переводили DWH Яндекс GO на рельсы Data Mesh. Женя там явно ссылается на предыдущий рассказ ↑ о метриках ДВХ, поэтому лучше начать с предыдущего.

Когда DWH достигает определённого размера, то теряется скорость и адаптивность — всё как у стартапа, переходящего к большой компании.

В мире разработки в таких случаях принято распиливать монолит на микросервисы, а на просторах DWH консалтеры из Thoughtworks в лице Zhamak Dehghani придумали парадигму Data Mesh. Это когда в DWH есть условно независимые архитектурные кванты с единой платформой и под общим федеративно-архитектурным присмотром.

На практике это выглядело как выделение команд в отдельные ДВХ. Мы съехали со своими етл-пайплайнами на отдельный «етл-сервис» с независимым циклом релиза. А потом постепенно забрали все свои сущности в отдельные схемы-домены.

Получается, раньше аналитики и менеджера Доставки носили свои хотелки в DWH Такси, а после разъезда им стало ходить ближе — появилось «своё» DWH, плотно погруженное в доменную область.

из недостатков:
⁃ пришлось перетащить кажется все сущности в другие папки-схемы. Некоторые по несколько раз >_< Не обошлось без сопутствующих проблем: очевидцы вспоминают процесс не иначе как «демонизация» (вместо официального «доменизация»)
⁃ при делении техническая экспертиза распределилась неравномерно между командами

в вопросах после доклада кто-то «из зала» обратил внимание на схожесть описанного Женей процесса на внедрение аджайла — поверим ему на слово =)

https://youtube.com/watch?v=XCnHS_lXHAA&si=EnSIkaIECMiOmarE
👍3
иллюстрация «как должен выглядеть Data Mesh» из той самой статьи от Zhamak Dehghani из 2020 года

https://martinfowler.com/articles/data-mesh-principles.html

сверху купол федеративного арх-надзора с документами-инструкциями

в центре слои-домены с выделенными командами

в основании — общая платформа для того, чтобы всё работало
👍1🔥1
NoSQL → Not Only SQL

NoSQL сейчас употребляется в смысле anti-SQL, как противопоставление доминирующим ораклам и постягрям с их ненавистной реляционной моделью.

Хотя изначально смысл закладывался другой — не прямое противопоставление, а как ещё один вариант, алтернатива. В Книге С Кабанчиком Мартин Клеппманн приводит ссылку на заметку из 2009 года.

https://web.archive.org/web/20190623045155/http://blog.sym-link.com/2009/10/30/nosql_whats_in_a_name.html

Действительно это был просто хэштег для митапа по альтернативным базам данных. Хештег потом прилепился, но смысл его постепенно стал более категоричным.

А изначально было действительно в значение Not Only SQL.

и ещё вот твит от фаундера графовой БД Neo4j из того же 2009
https://twitter.com/emileifrem/status/5200345765
🔥1
Легенды базостроительства в подкасте от dbt

Mike Stonebraker занимается базами данных с 1970-х. Тогда он написал реляционную БД Ingress, за три года до того как Ларри Эллисон выпустил Oracle. После этого Майкл приложил руку к Postgres (название отсылает к Ingres).

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

В 2005 они выпустили Вертику. Понравилась байка как они пришли показывать Вертику в большой тогдашний е-ком. Там был инстанс Оракла за миллион долларов, который обрабатывал аналитический запрос сутки. Команда Майка установила им Вертику, закачала туда их данные и тот же запрос отработал уже за секунды. Вот она вся прелесть DWH.

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

Вообще, судя по Википедии, дядьке 79 лет! Он уже как полвека что-то делает полезное, написал несколько популярных движков бд и кажется не планирует останавливаться. Вот сейчас мутит очередной дата-стартап. Говорит, что ему скучно просто лежать на пляже =)

https://roundup.getdbt.com/p/ep38-a-romp-through-database-history
👍6🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
в каждом меме есть доля шутки — в далёком 2020 я присматривался куда пойти… и не пошёл в ML 🙃 типа ща я тут по-быстрому с аналитикой сперва разберусь, а там до мл уже шапкой докинуть!
🔥19👍3
короткой строкой про дата-инженерские вакансии в Яндексе:

1. открыта вакансия в Практикум. Судя по описанию, всё довольно стандартно: там собрать, сюда положить, сверху витрины; ждут кандидатов с 3+ годами опыта. Если я ничего не путаю, Практикум работает удалённо, а ещё там супер душевная команда ❤️

2. а ещё случайно узнал, что 4-5 марта (это уже ЗАВТРА!) можно получить фаст оффер в DWH Яндекс Маркета. Про требования к кандидатам всё написано общо́. Маркет использует подходы к двх-строению как у нас в Go, поэтому там должно быть круто. Я б сходил чисто по фану — часто перетереть за данные с умными людьми без каких-то обязательств 😉

3. ну и к нам в Доставку тоже ищут инженера. У нас YT (Hadoop) + Greenplum, свой etl-фрейморк, работающий data mesh и свой анкор-моделинг для дата-ценителей. Тут уже могу рассказать всё в деталях, если будет интересно.
🔥12
деньги-денежки-деньжата

так-так-так, что тут у нас? это же зарплаты дата-профессий в Европе!

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

ребята собрали статистику по 500 вакансиям, сконвертили всё в доллары и сделали разрезы по синьорности, стране и компаниям.


что интересного увидели:

1. по синьорности: зп есть прямая корреляция на первых 6 лет карьеры, дальше всё по-разному

2. по локациям: в Берлина в среднем зп ниже, объясняют наличием там офисов Delivery Hero и Zalando, где зп чуть ниже рынка. А вот в Дублине, кажется, собрались сеньёристые ребята и там явный перекос зп в сторону высоких грейдов.

3. по компаниям: Delivery Hero и Zalando находятся где-то слева на распределении зп (см. п2 про них). А вот в Мете, Амазоне и Букинге есть выбросы по зп даже для мидлов — вот кому хорошо)


⌘ для нашего рынка раньше такое делали Хабр в 2021 и New.HR в 2019

за ссылку спасибо подборке от дата-кофе
👍6
#послушано

доклад Ивана Ямщикова на TechTrain про практические применения МЛ — от банальных до продвинутых. Медицина, легал и прочие отрасли. В конце общее (позитивное!) напутствие.

> Какие сейчас перед нами сценарии развития искусственного интеллекта? Ждет ли нас еще одна «зима»? Как машинное обучение меняет рынки, общества и планету?

iTunes, YouTube

⌘⌘⌘

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

iTunes, YouTube

⌘⌘⌘

Спотифай делает аккуратный шажочек в голосовые помощники. Там взяли крутого диджея, заперлись с ним в студии и сделали персонального диджея для каждого пользователя Спотифай. МЛ-диджей объявляет следующие треки и иногда делает вставки с фан-фактами об исполнителе. Примечательно, что диджей интегрирован с рекомендательной системой и может комментировать почему та или иная песня попала именно в твой плейлист.

iTunes

#подкаст
👍4
Промпт-инженеры

Зацепила фраза Григория Бакунова (bobuk) про промт для GitHub Copilot (работает на ChatGPT):

> Для тех кто не программирует, посмотрите на картинку — вот так выглядит будущее программирование искусственного интеллекта.

Действительно эти ~25 предложений можно представить как ~25 абзацев кода для какого-то приложения.

Продолжая аналогию с программированием, можно вспомнить с чего начинается почти каждый урок — тот самый Hello world! И то же самое происходит с тем, кто впервые сталкивается с гот-моделями — их промты простые и односложные.

А вот продвинутые юзеры гпт-моделей через пробы и ошибки учатся улучшают свои промты и некоторые уже даже не помещаются на страницу. Чем не продвинутая программа уже?

Получается, придумали весь этот МЛ, чтобы не писать кучу IF’ов — и теперь пишем эти же ифы, только теперь на естественном языке.
👍2
потрёпанный жизнью книжным клубом Кабанчик
👍2
Книжный клуб + Кабанчик = 🖤

Два года назад как начинающий и ответственный дата-инженер заказал оригинал книги Мартина Клеппманна Designing Data-Intensive Applications с Амазона. Но книга так и лежала у меня с тех пор, не смотря на рейтинг 5.0 и рекомендации со всех сторон.

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

План был максимальной простой: одна глава = одна неделя. Встречаемся каждый четверг, обсуждаем прочитанное, вспоминаем байки из опыта (если есть), находим аналоги в нашей инфраструктуре. И вот спустя 12 недель Кабанчик прочитан, книга исчёркана карандашными заметками, в заметках осталось 12 относительно структурированных конспектов.

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

Заметки на будущее: сложность материала возрастает к последним главам. В первых Мартин описывает базовые концепции и повествование в следующих главах строит уже поверх них. Последние несколько глав можно смело делить на два захода, потому как 50-60 страниц технического текста за неделю осилить уже сложновато.

Отдельно стоит отметить примечания к каждой главе. Мартин скрупулёзно собирал источники для каждого тезиса. В заметках можно найти научные работы, датированные начиная с 1960-х и до 2018 (года публикации книги). Для желающих копнуть глубже можно всегда обратиться к оригиналам.
🔥17
#послушано


🎈 Алексей Миловидов в «Запуск завтра» рассказал про то как начинал ClickHouse и к чему это всё привело

в 2008 это был просто конструктор отчётов для Яндекс Метрики, просто какие-то базовые отчёты на основе неагрегированных логов тогдашнего рунета. Потом была пауза в развитии и вернулся к разработке в 2011, чтобы в следующем году уже на основе Кликхауса вышла Метрика 2.0

Постепенно соседние отделы тоже интересовались возможностью быстро обрабатывать тонны логов и Кликхаус распространялся внутри Яндекса.

В 2016 решили выложить КХ в опенсорс — были опасения про безопасность, но плюсы этого решения оказались существеннее. А недавно КХ отделился совсем и стал стартапом с завидной оценкой и хорошими инвесторами. Развивают облачную версию и за несколько дней до подкаста запустили поддержку managed ClickHouse в GCP.

Понравился тезис Алексея что они стараются держать кодовую базу максимально простой — сейчас она порядка 800К строк против 2 млн у Postgres или MySQL. С определённого порога сложности вся структура перестаёт влезать в голову и скорость введения новых фич сильно замедляется. Чтобы в коде не оставалось непонятных костылей сбоку они регулярно переписывают или выпиливают совсем старые куски кода.

ссылки на послушать в канале подкаста

⌘⌘⌘


🎈 Антон Жиянов просветил «Подлодку» про SQL

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

Для себя повторил индексы, транзакции и узнал про безопасность. Понравилось тема с документно-ориентированными базами данных: сначала все побежали в nosql, а потом в Постгрес добавили поддержку json (не без помощи этого nosql хайпа), и теперь те же документы эффективнее делать в старом обычном SQL.

Антон сделал подробные таймкода в своём канале, не буду переписывать оттуда темы)

⌘⌘⌘


🎈 Иван Ямщиков и Григорий Бакунов обсудили что там с генеративными нейросетями и куда всё идёт

работа над кодом вместе с ChatGPT напоминает работу с джуном: ты ему говоришь что-то сделать, он приносит результат и потом ты это переделываешь «как правильно»

в будущем будет профессия «оператор Copilot» — можно будет не писать код, а писать инструкции для LLM-моделей, чтобы те уже дали нужный код. Это чем-то напоминает чернокнижников прошлого, когда те пытались заклинаниями вызвать демона для определённой работы.

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

по статистике порядка ~30% новых браков заключаются между людьми, познакомившихся в соцсетях. А поскольку используемые модели представляют собой черный ящик без возможности интерпретации результатов, то нельзя с уверенностью сказать, что нейросети уже сейчас не занимаются селекцией человеков, более склонных к залипанию в соцсетях 🌚

В канале подкаста есть ссылка на Ютуб, Apple Podcasts

#подкаст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3
🤓 data-архитектуры: Lamda vs Kappa

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

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

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

но всем хотелось сейчас и сразу, поэтому придумали как совместить эти два подхода

🔵 Lambda-архитектура

идея простая: когда хочется стриминг, но он ещё ненадёжный, делаем два потока данных:
1. текущий инкремент бежит через стриминг
2. а потом по старинке сверху накатываем батч

получается и быстро (но не надёжно), и eventually надёжно — после того как накатился следующий батч.

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

http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html

🟡 Kappa-архитектура

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

А если (когда!) надо будет пересчитать историю, то мы просто будем держать в памяти данные за нужный период и запускать новые версию джобов поверх них. Автор приводит пример что они в Линкедине таким образом держат в памяти 30 дней и для отдельных сущностей это может быть «терабайты».

http://radar.oreilly.com/2014/07/questioning-the-lambda-architecture.html

Звучит интересно, но пока не понял, как при каппа-архитектуре работают бекфилы? что делать, если надо пересчитать не 30 дней, а все данные за всю историю?
🔥74👍2
👆 Минутка кибербезопасности

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

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

кулстори: для одной компании делали аудит, сделали скан и нашли забытый всеми почтовый сервис, торчащий наружу. Спарсили с Линкедина сотрудников, сгенерерили почтовые адреса и по всем прошлись проверкой на базовые пароли — нашёлся один с условным qwerty. Зашли внутрь и пошли гулять там по внутренней сети по соседним сервисам, наткнулись на незашифрованный бекап хранилища паролей. Редкий случай, но довольно показательный.

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

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

вторая половина подкаста была про то как это всё работает в мире блокчейна и крипты — там полный дикий запад, поэтому особенно интересно послушать.

https://t.me/ctodaily/1684
🔥7👍21
🤓️Практикум: английский для разработчиков

Спустя 6 месяцев закончил курс, куда записался на панике сразу после мобилизации. На самом деле записался сразу на два английских от Практикума: общий и для разработчиков.

Общий порадовал короткими кусочками — в любое свободное время за 15 минут проходишь теорию и после неё записываешься на практику на через-5-минут. Можно не держать в голове расписание, а заниматься по свободности.

Но в итоге продолжил только с курсом английский для разработчиков. Там подкупила релевантность тем — всё связаны с ежедневной работой: стендапы и ретро, парное программирование и код-ревью, вопросы в интернете и публичная презентация; и конечно поиск работы и тренировка технических и бихейв интервью.

Процесс

В самом начале был небольшой скрининг, проверяли мой английский (видимо, что я смогу общаться с преподом без русского)

А дальше занятия 1-1 по зуму. Преподаватель шарит экран с уроками из Ноушена и мы вместе проходим. Там на понимание, на чтение и много на пересказ и прочие болталки.

После занятия идут домашки (препод ещё спрашивал в начале нужны ли они, буду ли я их делать)). Домашки на той же платформе, где и занятия по обычному английскому.

Каждое 8-е занятие идёт с носителем. За время обучения у меня были разные ребята из Милана, Австралии, Турции, США и Сингапура. У них был разный уровень английского — двое точно не нейтивы. Но в целом норм, они типа те самые айтишники, об которых можно потренироваться: отработать поведенческие и технические интервью.

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

полгода назад было два курса: для разработчиков и аналитиков. Сейчас вижу добавили третий (и расширили старые):
1. для разработчиков и QA
2. для продактов и прожектов
3. для аналитиков и DS

https://practicum.yandex.ru/english/english_for_career-1/
🔥18