В этом посте рассмотрим поиск заданного списка слов в миллионах документов, на основе примера задачи из книги “Cracking the coding interview”.
У нас есть миллион документов, и список слов. Нужно найти все документы, которые содержат все заданные слова. Слова в документе могут располагаться в произвольном порядке. Но слово не должно быть частью какого-то другого слова. Например, “кофе” не равно “кофемашина”.
Для начала надо выяснить, будет ли наша функция поиска вызвана единожды или много раз? Предположим, функция будет вызываться много раз, поэтому резонно с точки зрения производительности провести предварительные преобразования.
https://dmatveeva.github.io/search-words-in-millon-docs/
У нас есть миллион документов, и список слов. Нужно найти все документы, которые содержат все заданные слова. Слова в документе могут располагаться в произвольном порядке. Но слово не должно быть частью какого-то другого слова. Например, “кофе” не равно “кофемашина”.
Для начала надо выяснить, будет ли наша функция поиска вызвана единожды или много раз? Предположим, функция будет вызываться много раз, поэтому резонно с точки зрения производительности провести предварительные преобразования.
https://dmatveeva.github.io/search-words-in-millon-docs/
Подготовка к интервью по System Design
Поиск слов в миллионах документов
В этом посте рассмотрим поиск заданного списка слов в
миллионах документов, на основе примера задачи из книги “Cracking the coding interview”.
миллионах документов, на основе примера задачи из книги “Cracking the coding interview”.
В этом посте разберем еще одну задачу из книги Cracking the coding interview. Изначально задача про биржу, но мне кажется удобнее ее немного обобщить.
https://dmatveeva.github.io/how-to-distribute-data/
https://dmatveeva.github.io/how-to-distribute-data/
Подготовка к интервью по System Design
Как передавать пользователю данные?
В этом посте разберем еще одну задачу из книги Cracking the coding interview.
Задача про биржу, но мне кажется удобнее ее немного обобщить, что я и сделала в заголовке.
Задача про биржу, но мне кажется удобнее ее немного обобщить, что я и сделала в заголовке.
Завела канал на Youtube - https://www.youtube.com/@SystemDesign_Matveeva
И смонтировала первое видео :)
https://www.youtube.com/watch?v=sk-w0bWJaPA
И смонтировала первое видео :)
https://www.youtube.com/watch?v=sk-w0bWJaPA
YouTube
Масштабируем веб-сайт
В этом видео рассказываю некоторые стратегии масштабирования веб-сайтов. Они помогут обеспечить работу системы, когда количество пользователей растет с одного до миллиона.
❤1👍1
Что такое протокол gossip, где применяется и для чего?
https://dmatveeva.github.io/gossip-protocol/
https://dmatveeva.github.io/gossip-protocol/
System Design
Протокол gossip
В этом посте - поверхностный обзор протокола Gossip.
Немного об устройстве компьютера и реализации многопоточности.
https://dmatveeva.github.io/how-computer-works/
https://dmatveeva.github.io/how-computer-works/
System Design
Как работает компьютер
В этом посте я бы хотела рассказать об устройстве компьютера и затронуть тему реализации многопоточности.
Немного о скоростях, с которыми работает компьютер, и ссылки на инфографику:
https://dmatveeva.github.io/latency-numbers/
https://dmatveeva.github.io/latency-numbers/
System Design
Как быстро работает компьютер
C какой скоростью работает компьютер? Примерные цифры - в таблице.
Версионирование базы данных с Liquibase:
https://dmatveeva.github.io/liquibase/
https://dmatveeva.github.io/liquibase/
System Design
Liquibase
Как произвести изменение схемы базы данных в работающем приложении?
👍1
Первый пост-обзор на книгу "Микросервисы. Паттерны разработки и рефакторинга".
https://dmatveeva.github.io/microservices/
https://dmatveeva.github.io/microservices/
System Design
Микросервисная vs. Монолитная архитектура
В этом посте начну обзор книги “Микросервисы. Паттерны разработки и рефакторинга” Криса Ричардсона.
Рассмотрим, чем микросервисная архитектура отличается от монолитной, их преимущества и недостатки.
Рассмотрим, чем микросервисная архитектура отличается от монолитной, их преимущества и недостатки.
🔥2
Сейчас наша команда активно ищет новых разработчиков на Java, и я уже несколько недель участвую в собеседованиях.
Наблюдения:
▫️ Теперь понимаю, почему иногда, будучи кандидатом, получала вопросы, казавшиеся странными.
Например вопрос интервьюера, много ли вы писали кода на рабочем месте? Казалось бы, конечно, ведь я разработчик. Но вот например один из кандидатов сказал, что уже несколько месяцев не пишет код, а занимается задачами devops, хотя в резюме как раз указано разработчик .
▫️ Обычно наш тимлид дает несколько фрагментов кода и просит найти и исправить ошибку. И почему-то кандидаты неохотно пишут код. Большинство людей просто размышляли вслух, всего пару человек писали и исправляли. Один из них правда не приблизился к решению, но начал активно рефакторить существующие классы, из-за чего решение перестало компилироваться.
▫️И уже несколько человек сказали, что долго работали в реактивном стэке, и поэтому забыли Hibernate.
Наблюдения:
▫️ Теперь понимаю, почему иногда, будучи кандидатом, получала вопросы, казавшиеся странными.
Например вопрос интервьюера, много ли вы писали кода на рабочем месте? Казалось бы, конечно, ведь я разработчик. Но вот например один из кандидатов сказал, что уже несколько месяцев не пишет код, а занимается задачами devops, хотя в резюме как раз указано разработчик .
▫️ Обычно наш тимлид дает несколько фрагментов кода и просит найти и исправить ошибку. И почему-то кандидаты неохотно пишут код. Большинство людей просто размышляли вслух, всего пару человек писали и исправляли. Один из них правда не приблизился к решению, но начал активно рефакторить существующие классы, из-за чего решение перестало компилироваться.
▫️И уже несколько человек сказали, что долго работали в реактивном стэке, и поэтому забыли Hibernate.
👍2😁2
Сейчас на нашем проекте идет активный перевод существующих spring boot микросервисов с oracle на postgres. Задача разработчика - адаптировать нативные запросы, затем завести микросервис локально у себя на машине и вызвать пару эндпойнтов, чтобы убедиться в минимальной работоспособности. Затем микросервис развертывается на дев стенде и передается в тестирование QA команде.
Этот процесс осложняется тем, что микросервисы часто имеют множество зависимостей от других микросервисов, и чтобы запустить один, нужно запустить несколько других.
И вдобавок, не все сервисы содержат юнит-тесты.
Поэтому нужно было писать довольно много тестов. И очень удобно оказалось запускать их лишь для репозиториев с нативными запросами, не поднимая весь контекст спринга:
1. К тестовому классу добавила аннотацию DataJpaTest (вместо SpringBootTest, которая поднимает весь контекст)
2. DataJpaTest использует embedded in-memory БД. Чтобы подключиться к нужной базе, использовала AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
3. Ну и ActiveProfile("test"), чтобы Spring Boot подхватил параметры подключения к базе из профиля test в test-application.yml
И когда нативные запросы отлажены с помощью такой конфигурации, для тестирования эндпойнтов использую MockMvc.
А в планах разобраться с WireMock, чтобы мокировать запросы к другим сервисам, и, соответственно, избавиться от необходимости дополнительно их развертывать.
#рабочее
Этот процесс осложняется тем, что микросервисы часто имеют множество зависимостей от других микросервисов, и чтобы запустить один, нужно запустить несколько других.
И вдобавок, не все сервисы содержат юнит-тесты.
Поэтому нужно было писать довольно много тестов. И очень удобно оказалось запускать их лишь для репозиториев с нативными запросами, не поднимая весь контекст спринга:
1. К тестовому классу добавила аннотацию DataJpaTest (вместо SpringBootTest, которая поднимает весь контекст)
2. DataJpaTest использует embedded in-memory БД. Чтобы подключиться к нужной базе, использовала AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
3. Ну и ActiveProfile("test"), чтобы Spring Boot подхватил параметры подключения к базе из профиля test в test-application.yml
И когда нативные запросы отлажены с помощью такой конфигурации, для тестирования эндпойнтов использую MockMvc.
А в планах разобраться с WireMock, чтобы мокировать запросы к другим сервисам, и, соответственно, избавиться от необходимости дополнительно их развертывать.
#рабочее
❤3👍1🔥1
Продолжаю заметки по миграции spring boot микросервисов с oracle на postgres.
Во время адаптации миграции несколько раз сталкивалась с особенностями конвертации полей различных типов в двух БД.
Вот несколько примеров:
✔️ В oracle в нативном запросе есть джойн по колонкам с типами varchar and number.
Например:
Oracle неявно делает конвертацию
✔️Изначально в oracle в таблице БД есть колонка с типом number, а в коде, в сущности hibernate, она маппится на поле с типом String. В postgres колонка мигрирует с типом bigint. При работе приложения, oracle спокойно делает конвертацию, а postgres выдает ошибку на несоответствие типов.
Решение - заменить тип поля в сущности на Long.
Чуть было не пропустила эту ошибку, т.к. на первых порах писала тесты лишь для тех методов репозиториев, где объявлены нативные запросы. А она обнаружилась случайно как раз для сущности, для которой нет таких методов. После этого начала писать тесты вообще для всех сущностей и отловила не одну такую ситуацию.
✔️ В oracle в таблице БД есть колонка с типом varchar, которая маппится на поле с типом boolean. Предполагается, что в БД значения колонки 0/1.
Опять же, oracle конвертирует, а для корректной работы в postgres, нужно добавить аннотацию
#рабочее
Во время адаптации миграции несколько раз сталкивалась с особенностями конвертации полей различных типов в двух БД.
Вот несколько примеров:
✔️ В oracle в нативном запросе есть джойн по колонкам с типами varchar and number.
Например:
create table employee ( id number )
create table tasks ( id number, employee_id varchar )
select * from employee e join tasks t on e.id = t.employee_id;
Oracle неявно делает конвертацию
to_number(t.employee_id)=e.id, и если в таблице employee колонка employee_id содержит только строки, которые можно конвертировать в число, то запрос отработает нормально. Но postgres выдаст ошибку, и для решения нужно будет явно привести один тип к другому.✔️Изначально в oracle в таблице БД есть колонка с типом number, а в коде, в сущности hibernate, она маппится на поле с типом String. В postgres колонка мигрирует с типом bigint. При работе приложения, oracle спокойно делает конвертацию, а postgres выдает ошибку на несоответствие типов.
Решение - заменить тип поля в сущности на Long.
Чуть было не пропустила эту ошибку, т.к. на первых порах писала тесты лишь для тех методов репозиториев, где объявлены нативные запросы. А она обнаружилась случайно как раз для сущности, для которой нет таких методов. После этого начала писать тесты вообще для всех сущностей и отловила не одну такую ситуацию.
✔️ В oracle в таблице БД есть колонка с типом varchar, которая маппится на поле с типом boolean. Предполагается, что в БД значения колонки 0/1.
Опять же, oracle конвертирует, а для корректной работы в postgres, нужно добавить аннотацию
@Type(type="org.hibernate.type.NumericBooleanType") на поле сущности.#рабочее
🫡3