Внутренний диалог и иностранный язык
Продолжу тему иностранного языка. Как вы знаете, я активно практикую йогу, потому что она помогает решать самые разные задачи в физическом и ментальном плане. В физическом плане всё понятно: асаны в йоге можно сравнить с любимыми спортивными упражнениями, но в спорте нет ментальных практик. Если упростить, йога — это концентрация на объекте наблюдения, например на дыхании, или, наоборот, на мыслительном процессе, но без погружения в него.
Попробуйте сами непрерывно понаблюдать за дыханием — через короткий промежуток времени вы поймаете себя на мысли, что уже не наблюдаете за дыханием, а думаете о других вещах.
На самом деле процесс переключения крайне важен, так как он позволяет найти опору в мыслительной деятельности. Наш ум всегда находится в потоке мыслей — это его природа. Как река не может стоять на месте, так и ум не может молчать, но мы можем им управлять.
Приведу пример: когда мы читаем про себя, у нас работает внутренний диалог, а когда мы читаем вслух, внутреннего диалога уже нет. Поэтому психологи часто рекомендуют общаться с друзьями, чтобы развеять плохие мысли: в процессе общения внутренний диалог переключается на внешний, что позволяет успокоить ум.
Тот же феномен работает и с иностранным языком: если мы читаем, мыслительный диалог идёт на этом языке. Поэтому, если есть возможность, читайте вслух.
Этот же приём используется при чтении программного кода.
Посмотрите на пример кода на Rust:
Я уверен на 100%, что вы смогли прочитать и понять этот код. Обратите внимание, что ваш мозг интерпретировал его по-своему, даже без знания синтаксиса Rust. Вам, конечно, не понятны все нюансы, но общий смысл вы уловили: описать структуру данных, дать ей функцию, создать объект этой структуры и вызвать функцию.
А теперь вернёмся к английскому языку. У меня появилась идея создать серию уроков, которая позволит читать английские книги и статьи в оригинале. Составить такой материал через ChatGPT несложно. Для чтения Reddit нужен словарный запас около 4000–6000 слов — это вполне реально, ведь многие IT-термины либо вовсе не переводятся (например, «commit»), либо имеют аналогичное звучание (например, «transaction»).
Однако встал вопрос: что делать с внутренним диалогом? Проблема в том, что мы будем неправильно произносить английские слова, но я пришёл к выводу, что это не так важно. Главное — отказаться от дословного перевода, как в примере с Rust-кодом, и сосредоточиться на понимании смысла предложения, а не на буквальном переводе.
Я знаю, что среди моей аудитории есть лингвисты. Если у кого-то есть желание принять участие в этом проекте, пишите мне @parsentev.
Продолжу тему иностранного языка. Как вы знаете, я активно практикую йогу, потому что она помогает решать самые разные задачи в физическом и ментальном плане. В физическом плане всё понятно: асаны в йоге можно сравнить с любимыми спортивными упражнениями, но в спорте нет ментальных практик. Если упростить, йога — это концентрация на объекте наблюдения, например на дыхании, или, наоборот, на мыслительном процессе, но без погружения в него.
Попробуйте сами непрерывно понаблюдать за дыханием — через короткий промежуток времени вы поймаете себя на мысли, что уже не наблюдаете за дыханием, а думаете о других вещах.
На самом деле процесс переключения крайне важен, так как он позволяет найти опору в мыслительной деятельности. Наш ум всегда находится в потоке мыслей — это его природа. Как река не может стоять на месте, так и ум не может молчать, но мы можем им управлять.
Приведу пример: когда мы читаем про себя, у нас работает внутренний диалог, а когда мы читаем вслух, внутреннего диалога уже нет. Поэтому психологи часто рекомендуют общаться с друзьями, чтобы развеять плохие мысли: в процессе общения внутренний диалог переключается на внешний, что позволяет успокоить ум.
Тот же феномен работает и с иностранным языком: если мы читаем, мыслительный диалог идёт на этом языке. Поэтому, если есть возможность, читайте вслух.
Этот же приём используется при чтении программного кода.
Посмотрите на пример кода на Rust:
struct SeaCreature {
noise: String,
}
impl SeaCreature {
fn get_sound(&self) -> &str {
&self.noise
}
}
fn main() {
let creature = SeaCreature {
noise: String::from("blub"),
};
println!("{}", creature.get_sound());
}Я уверен на 100%, что вы смогли прочитать и понять этот код. Обратите внимание, что ваш мозг интерпретировал его по-своему, даже без знания синтаксиса Rust. Вам, конечно, не понятны все нюансы, но общий смысл вы уловили: описать структуру данных, дать ей функцию, создать объект этой структуры и вызвать функцию.
А теперь вернёмся к английскому языку. У меня появилась идея создать серию уроков, которая позволит читать английские книги и статьи в оригинале. Составить такой материал через ChatGPT несложно. Для чтения Reddit нужен словарный запас около 4000–6000 слов — это вполне реально, ведь многие IT-термины либо вовсе не переводятся (например, «commit»), либо имеют аналогичное звучание (например, «transaction»).
Однако встал вопрос: что делать с внутренним диалогом? Проблема в том, что мы будем неправильно произносить английские слова, но я пришёл к выводу, что это не так важно. Главное — отказаться от дословного перевода, как в примере с Rust-кодом, и сосредоточиться на понимании смысла предложения, а не на буквальном переводе.
Я знаю, что среди моей аудитории есть лингвисты. Если у кого-то есть желание принять участие в этом проекте, пишите мне @parsentev.
🔥12
String в Java и Go
Как вы знаете, задача на работе и задача на собеседовании — это две совершенно разные вещи.
Напомню, что с Михаилом мы решили провести эксперимент с языком Go (GoLang). Эксперимент крайне простой: за 4–5 месяцев проработать материал по Go и вкатиться в Go-разработку без потери зарплаты.
Я сразу разделил это на два процесса: реальные задачи на работе и вопросы/задачи для собеседования.
В этой статье мы поговорим о вопросах, задаваемых на собеседовании.
Вас когда-нибудь спрашивали на собеседовании по Java о том, как устроен класс
Давайте разберёмся.
В Go строка (
Символы в кодировке UTF-8 могут занимать от 1 до 4 байтов. Поэтому в Go есть тип
Здесь
Если в строку попадают байты, не составляющие корректную UTF-8-последовательность, Go при разборе рун заменяет такой фрагмент на специальный символ
А как обстоят дела в Java?
В классическом варианте строки в Java представлены массивом 16-битных символов (UTF-16):
Начиная с Java 9 появился механизм оптимизации Compact Strings:
- Строки, содержащие только символы из Latin-1 (U+0000…U+00FF), хранятся по 1 байту на символ.
- Как только встречается хотя бы один символ за пределами Latin-1, используется UTF-16 (2 байта на кодовую единицу).
В Java тоже есть методы для работы с кодовыми точками:
Как вы знаете, задача на работе и задача на собеседовании — это две совершенно разные вещи.
Напомню, что с Михаилом мы решили провести эксперимент с языком Go (GoLang). Эксперимент крайне простой: за 4–5 месяцев проработать материал по Go и вкатиться в Go-разработку без потери зарплаты.
Я сразу разделил это на два процесса: реальные задачи на работе и вопросы/задачи для собеседования.
В этой статье мы поговорим о вопросах, задаваемых на собеседовании.
Вас когда-нибудь спрашивали на собеседовании по Java о том, как устроен класс
String? Думаю, нет, разве что о String Pool. А вот в Go это обязательный вопрос.Давайте разберёмся.
В Go строка (
string) — это неизменяемая (immutable) последовательность байтов, обычно кодирующих UTF-8. Под капотом строка представлена простым «хэдером» из двух машинных слов:// в пакете reflect есть аналогичная структура:
type StringHeader struct {
Data uintptr // указатель на первый байт в памяти
Len int // длина в байтах
}
Символы в кодировке UTF-8 могут занимать от 1 до 4 байтов. Поэтому в Go есть тип
rune: он позволяет прочитать нужное количество байтов, чтобы получить соответствующий символ из таблицы Unicode:name := "Hello, 世界"
for i, r := range name {
fmt.Println(i, string(r), r)
}
Здесь
i указывает на начало руны.Если в строку попадают байты, не составляющие корректную UTF-8-последовательность, Go при разборе рун заменяет такой фрагмент на специальный символ
� (U+FFFD), а длина такого «руна-элемента» считается равной 1 байту:b := []byte{0xff, 0xfe, 0x41} // 0x41 == 'A'
s := string(b)
fmt.Printf("len(bytes) = %d, len(runes) = %d\n",
len(b),
utf8.RuneCountInString(s),
)
// При range по строке
for i, r := range s {
fmt.Printf("idx %d: rune %U '%c'\n", i, r, r)
}А как обстоят дела в Java?
В классическом варианте строки в Java представлены массивом 16-битных символов (UTF-16):
public final class String {
private final char[] value;
private int hash;
// ...
}Начиная с Java 9 появился механизм оптимизации Compact Strings:
public final class String {
private final byte[] value;
private final byte coder; // 0 — LATIN1, 1 — UTF16
private int hash;
// ...
}- Строки, содержащие только символы из Latin-1 (U+0000…U+00FF), хранятся по 1 байту на символ.
- Как только встречается хотя бы один символ за пределами Latin-1, используется UTF-16 (2 байта на кодовую единицу).
В Java тоже есть методы для работы с кодовыми точками:
String.codePointAt() и String.codePoints().❤1
Алго-марафон | 2 неделя
Вначале хотел бы внести коррективы в план.
Изначальная идея заключалась в том, чтобы решать одну задачу в неделю. Но это крайне мало: такой темп годится разве что для того, чтобы не забыть совсем пройденный материал. Для нашего с Михаилом эксперимента такая скорость не подходит, поэтому пришлось внести изменения.
Примерно нужно решить 150 задач за 4–5 месяцев:
- Около 40 задач уровня easy.
- Около 100 задач уровня medium.
- И 10 задач уровня hard.
Выуживать задачи из YouTube оказалось неблагородным делом, ведь в 99 % это те же задачи с LeetCode. Поэтому я буду просто брать задачи оттуда.
Для задач easy и medium используем стандартный набор структур данных и алгоритмов:
- Два указателя
- Скользящее окно
- Бинарный поиск
- Хэш-таблица
- Стек
- Очередь
- Рекурсия
- Итерация
- Сортировка
- Префиксные суммы
- Жадные алгоритмы
- Битовые операции
- Динамическое программирование (простые задачи)
- BFS
- DFS
Всё это есть у нас в курсах: https://job4j.ru/profile/courses/5, https://job4j.ru/profile/courses/32 с теорией, задачами и проверкой менторами.
Поэтому на этой неделе нужно решить 10 задач уровня easy. Я приведу здесь ссылки на LeetCode, а завтра — аналоги на нашей платформе:
- https://leetcode.com/problems/two-sum/
- https://leetcode.com/problems/reverse-linked-list/
- https://leetcode.com/problems/valid-parentheses/
- https://leetcode.com/problems/merge-two-sorted-lists/
- https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
- https://leetcode.com/problems/maximum-subarray/
- https://leetcode.com/problems/valid-anagram/
- https://leetcode.com/problems/invert-binary-tree/
- https://leetcode.com/problems/move-zeroes/
- https://leetcode.com/problems/intersection-of-two-arrays/
Кстати, я решаю их на Go, потому что в нём есть только массивы и карты, то есть остальные структуры приходится реализовывать самостоятельно (например, LinkedHashMap или HashSet). Я также настоятельно рекомендую всем, кто участвует в нашем эксперименте с Go, прорешать эти задачи именно на Go.
Свои решения вы можете оставить в комментариях под этим постом.
Вначале хотел бы внести коррективы в план.
Изначальная идея заключалась в том, чтобы решать одну задачу в неделю. Но это крайне мало: такой темп годится разве что для того, чтобы не забыть совсем пройденный материал. Для нашего с Михаилом эксперимента такая скорость не подходит, поэтому пришлось внести изменения.
Примерно нужно решить 150 задач за 4–5 месяцев:
- Около 40 задач уровня easy.
- Около 100 задач уровня medium.
- И 10 задач уровня hard.
Выуживать задачи из YouTube оказалось неблагородным делом, ведь в 99 % это те же задачи с LeetCode. Поэтому я буду просто брать задачи оттуда.
Для задач easy и medium используем стандартный набор структур данных и алгоритмов:
- Два указателя
- Скользящее окно
- Бинарный поиск
- Хэш-таблица
- Стек
- Очередь
- Рекурсия
- Итерация
- Сортировка
- Префиксные суммы
- Жадные алгоритмы
- Битовые операции
- Динамическое программирование (простые задачи)
- BFS
- DFS
Всё это есть у нас в курсах: https://job4j.ru/profile/courses/5, https://job4j.ru/profile/courses/32 с теорией, задачами и проверкой менторами.
Поэтому на этой неделе нужно решить 10 задач уровня easy. Я приведу здесь ссылки на LeetCode, а завтра — аналоги на нашей платформе:
- https://leetcode.com/problems/two-sum/
- https://leetcode.com/problems/reverse-linked-list/
- https://leetcode.com/problems/valid-parentheses/
- https://leetcode.com/problems/merge-two-sorted-lists/
- https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
- https://leetcode.com/problems/maximum-subarray/
- https://leetcode.com/problems/valid-anagram/
- https://leetcode.com/problems/invert-binary-tree/
- https://leetcode.com/problems/move-zeroes/
- https://leetcode.com/problems/intersection-of-two-arrays/
Кстати, я решаю их на Go, потому что в нём есть только массивы и карты, то есть остальные структуры приходится реализовывать самостоятельно (например, LinkedHashMap или HashSet). Я также настоятельно рекомендую всем, кто участвует в нашем эксперименте с Go, прорешать эти задачи именно на Go.
Свои решения вы можете оставить в комментариях под этим постом.
🔥8
В Go за 5 месяцев. Горизонтальное масштабирование карьеры
Недавно читал про эксперимент ребят из Польши. Они фанатеют языком Go и хотели создать настолько плотный обучающий материал, чтобы за 10 часов перейти на Go в коммерческом проекте:
https://threedots.tech/post/we-quit-our-jobs/
Мне хотелось бы повторить их эксперимент, но в реалистичные сроки.
Изначально я разделил обучение на два параллельных процесса. Первый — то, что мы делаем на работе: микросервисы, REST, gRPC, Kafka, Docker, Kubernetes, Redis. Второй — то, что нужно для собеседования. Это два отдельных навыка.
Разберём, что нужно для работы:
1. Базовый синтаксис, ООП, ФП, структуры данных.
Учебный проект: телеграм-бот ToDo List с использованием PostgreSQL. Это позволит покрыть все основные темы языка, кроме корутин.
2. Корутины.
Учебный проект — классический граббер сайтов, например поиск вакансий на hh.ru.
3. Микросервисы.
Один сервис (gRPC + REST) общается со вторым через Kafka. JWT + Redis для авторизации и хранения сессий.
Разбор задач и вопросов на собеседовании (параллельный процесс, а не после первой части):
1. Алгоритмы и структуры данных: 40 easy, 100 medium, 10 hard.
2. Вопросы по корутинам и управлению памятью.
3. Системный дизайн.
Опыт работы?! Всё просто: в резюме указываем, что переписали какие-то микросервисы в своём проекте на Go — и они стали в разы быстрее. Поэтому хочется писать весь проект на Go, главное — самостоятельно переписать.
Эта схема подходит тем, кто уже работает с микросервисами.
Оцениваю такое обучение примерно в 5 месяцев ежедневных занятий, но никак не за 10 часов.
Зачем учить ещё один язык, решающий те же задачи, что и Java?
Во-первых, уровень абстракции: в Go вы ближе к системному программированию. Это особенно ценят на собеседованиях, например при вопросах о реализации строк или слайсов в Go.
Во-вторых, количество вакансий, на которые вы можете претендовать, сразу увеличивается вдвое. Стек остаётся одинаковым, меняется только базовый язык. Все концепции ООП, ФП, структуры данных, реляционные базы данных остаются такими же.
По сути это горизонтальное масштабирование вашей карьеры: резюме отличается только основным языком (Java или Go), а весь стек остаётся одинаковым.
Недавно читал про эксперимент ребят из Польши. Они фанатеют языком Go и хотели создать настолько плотный обучающий материал, чтобы за 10 часов перейти на Go в коммерческом проекте:
https://threedots.tech/post/we-quit-our-jobs/
Мне хотелось бы повторить их эксперимент, но в реалистичные сроки.
Изначально я разделил обучение на два параллельных процесса. Первый — то, что мы делаем на работе: микросервисы, REST, gRPC, Kafka, Docker, Kubernetes, Redis. Второй — то, что нужно для собеседования. Это два отдельных навыка.
Разберём, что нужно для работы:
1. Базовый синтаксис, ООП, ФП, структуры данных.
Учебный проект: телеграм-бот ToDo List с использованием PostgreSQL. Это позволит покрыть все основные темы языка, кроме корутин.
2. Корутины.
Учебный проект — классический граббер сайтов, например поиск вакансий на hh.ru.
3. Микросервисы.
Один сервис (gRPC + REST) общается со вторым через Kafka. JWT + Redis для авторизации и хранения сессий.
Разбор задач и вопросов на собеседовании (параллельный процесс, а не после первой части):
1. Алгоритмы и структуры данных: 40 easy, 100 medium, 10 hard.
2. Вопросы по корутинам и управлению памятью.
3. Системный дизайн.
Опыт работы?! Всё просто: в резюме указываем, что переписали какие-то микросервисы в своём проекте на Go — и они стали в разы быстрее. Поэтому хочется писать весь проект на Go, главное — самостоятельно переписать.
Эта схема подходит тем, кто уже работает с микросервисами.
Оцениваю такое обучение примерно в 5 месяцев ежедневных занятий, но никак не за 10 часов.
Зачем учить ещё один язык, решающий те же задачи, что и Java?
Во-первых, уровень абстракции: в Go вы ближе к системному программированию. Это особенно ценят на собеседованиях, например при вопросах о реализации строк или слайсов в Go.
Во-вторых, количество вакансий, на которые вы можете претендовать, сразу увеличивается вдвое. Стек остаётся одинаковым, меняется только базовый язык. Все концепции ООП, ФП, структуры данных, реляционные базы данных остаются такими же.
По сути это горизонтальное масштабирование вашей карьеры: резюме отличается только основным языком (Java или Go), а весь стек остаётся одинаковым.
👍14🔥1
Опять Кадане
Выше я привел список из 10 задача. Все задачи мне попадались раньше, кроме https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
Сначала я оценил, как бы ее сделал сам и кроме прямого перебора больше решение не придумал. Пошел смотреть предлагаемые решения и как оказалось, то опять тут алгоритм Кадане. Сходу его применить тут не смог.
Для тренировки сделал еще и задачи на поиск максимального подмассива.
Пока в голову этот алгоритм не залез. Для этого случая, мы ищем локальным минимум. Если мы нашли новый, минимум, то идем считать уже от него. Время получается линейное.
в случае с подмассивом, все тоже самое, только мы оцениваем сумму, а не одно число.
В целом пост о том, что я тоже делаю эти задачи, чтобы поддержать тех кто тоже решить в нем принять участие.
Выше я привел список из 10 задача. Все задачи мне попадались раньше, кроме https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
Сначала я оценил, как бы ее сделал сам и кроме прямого перебора больше решение не придумал. Пошел смотреть предлагаемые решения и как оказалось, то опять тут алгоритм Кадане. Сходу его применить тут не смог.
Для тренировки сделал еще и задачи на поиск максимального подмассива.
Пока в голову этот алгоритм не залез. Для этого случая, мы ищем локальным минимум. Если мы нашли новый, минимум, то идем считать уже от него. Время получается линейное.
в случае с подмассивом, все тоже самое, только мы оцениваем сумму, а не одно число.
В целом пост о том, что я тоже делаю эти задачи, чтобы поддержать тех кто тоже решить в нем принять участие.
👍9✍3
@Transation | Hibernate
У нас в курс https://job4j.ru/profile/courses/12 есть тестовое задание, где мы используем напрямую Hibernate.
https://github.com/MikhailChrn/job4j_cars/blob/10d435a795963ee839be915242001170ef0fdb39/src/main/java/ru/job4j/cars/repository/CrudRepository.java
Есть сервисы, которые не атомарно записывают данные.
Я попросил ученика сделать их атомарными. Я знаю, что это не тривиально в этом задании, потому что подобная проблема есть в Go.
Решение ученика.
https://github.com/MikhailChrn/job4j_cars/blob/10d435a795963ee839be915242001170ef0fdb39/src/main/java/ru/job4j/cars/service/impl/RegularPostService.java#L130-L140
Вопрос, можно ли так делать? Если нет, то как сделать правильно?
Решение пишите в комментариях к этому посту.
У нас в курс https://job4j.ru/profile/courses/12 есть тестовое задание, где мы используем напрямую Hibernate.
https://github.com/MikhailChrn/job4j_cars/blob/10d435a795963ee839be915242001170ef0fdb39/src/main/java/ru/job4j/cars/repository/CrudRepository.java
Есть сервисы, которые не атомарно записывают данные.
Я попросил ученика сделать их атомарными. Я знаю, что это не тривиально в этом задании, потому что подобная проблема есть в Go.
Решение ученика.
https://github.com/MikhailChrn/job4j_cars/blob/10d435a795963ee839be915242001170ef0fdb39/src/main/java/ru/job4j/cars/service/impl/RegularPostService.java#L130-L140
Вопрос, можно ли так делать? Если нет, то как сделать правильно?
Решение пишите в комментариях к этому посту.
GitHub
job4j_cars/src/main/java/ru/job4j/cars/repository/CrudRepository.java at 10d435a795963ee839be915242001170ef0fdb39 · MikhailChrn/job4j_cars
Contribute to MikhailChrn/job4j_cars development by creating an account on GitHub.
Задачи на эту неделю
https://leetcode.com/problems/climbing-stairs/
Темы: динамическое программирование
https://leetcode.com/problems/rotate-array/
Темы: массив, циклические сдвиги, реверс
https://leetcode.com/problems/third-maximum-number/
Темы: массив, сортировка или трёхкомнатный учёт
https://leetcode.com/problems/plus-one/
Темы: массив, симуляция сложения
https://leetcode.com/problems/pascals-triangle/
Темы: массив, динамическое программирование
https://leetcode.com/problems/intersection-of-two-linked-lists/
Темы: односвязный список, два указателя
https://leetcode.com/problems/linked-list-cycle/
Темы: односвязный список, два указателя (черепаха и заяц)
https://leetcode.com/problems/symmetric-tree/
Темы: дерево, рекурсия или BFS
https://leetcode.com/problems/single-number/
Темы: массив, побитовое XOR
https://leetcode.com/problems/majority-element/
Темы: массив, голосование Бойера–Мура или хэш-таблица
Черканите, в комментариях, кто еще пробует со мной этот марафон.
https://leetcode.com/problems/climbing-stairs/
Темы: динамическое программирование
https://leetcode.com/problems/rotate-array/
Темы: массив, циклические сдвиги, реверс
https://leetcode.com/problems/third-maximum-number/
Темы: массив, сортировка или трёхкомнатный учёт
https://leetcode.com/problems/plus-one/
Темы: массив, симуляция сложения
https://leetcode.com/problems/pascals-triangle/
Темы: массив, динамическое программирование
https://leetcode.com/problems/intersection-of-two-linked-lists/
Темы: односвязный список, два указателя
https://leetcode.com/problems/linked-list-cycle/
Темы: односвязный список, два указателя (черепаха и заяц)
https://leetcode.com/problems/symmetric-tree/
Темы: дерево, рекурсия или BFS
https://leetcode.com/problems/single-number/
Темы: массив, побитовое XOR
https://leetcode.com/problems/majority-element/
Темы: массив, голосование Бойера–Мура или хэш-таблица
Черканите, в комментариях, кто еще пробует со мной этот марафон.
LeetCode
Climbing Stairs - LeetCode
Can you solve this real interview question? Climbing Stairs - You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Example 1:
Input: n = 2…
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Example 1:
Input: n = 2…
👍4
Шаблон Request - Reply
Добавил урок в курс https://job4j.ru/profile/courses/21
Request-Reply шаблон [#505464]
У кого есть желание может попробовать решить задание тоже.
В этом уроке мы поговорим об асинхронной природе Kafka.
Сообщение, отправленное продюсером, попадает в брокер, и единственное, что мы можем получить в ответ, — это подтверждение о регистрации в брокере. О механизме доставки сообщений мы поговорим в другом уроке.
А теперь представьте ситуацию: у вас есть сервис A, который принимает от клиентов запрос через REST API. Ему нужны данные от сервиса B, который в вашей архитектуре общается только асинхронно, то есть через Kafka. Возникает неприятная ситуация конфликта двух идеологий: синхронного и асинхронного общения.
Очевидное решение такой проблемы — заблокировать синхронный вызов до момента прихода асинхронного ответа. Эта идея выражена в шаблоне Request-Reply. В Spring Cloud Kafka есть готовая реализация этого шаблона, но мы будем реализовывать её самостоятельно.
Сначала рассмотрим простую ситуацию без очередей.
* Thread — клиент REST API.
* Thread — асинхронный клиент Kafka.
* ReqReply — контейнер, который блокирует Thread REST API на заданное время. Если в это время приходит ответ от Thread Kafka, контейнер разблокируется и возвращает ответ.
Напомню, что здесь происходит:
—
—
Задание:
1. Доработайте код, приведённый выше, так, чтобы он работал с ключом
2. Добавьте тесты (три сценария):
*
*
*
3. Загрузите код в репозиторий и оставьте ссылку на изменения.
Добавил урок в курс https://job4j.ru/profile/courses/21
Request-Reply шаблон [#505464]
У кого есть желание может попробовать решить задание тоже.
В этом уроке мы поговорим об асинхронной природе Kafka.
Сообщение, отправленное продюсером, попадает в брокер, и единственное, что мы можем получить в ответ, — это подтверждение о регистрации в брокере. О механизме доставки сообщений мы поговорим в другом уроке.
А теперь представьте ситуацию: у вас есть сервис A, который принимает от клиентов запрос через REST API. Ему нужны данные от сервиса B, который в вашей архитектуре общается только асинхронно, то есть через Kafka. Возникает неприятная ситуация конфликта двух идеологий: синхронного и асинхронного общения.
Очевидное решение такой проблемы — заблокировать синхронный вызов до момента прихода асинхронного ответа. Эта идея выражена в шаблоне Request-Reply. В Spring Cloud Kafka есть готовая реализация этого шаблона, но мы будем реализовывать её самостоятельно.
Сначала рассмотрим простую ситуацию без очередей.
* Thread — клиент REST API.
* Thread — асинхронный клиент Kafka.
* ReqReply — контейнер, который блокирует Thread REST API на заданное время. Если в это время приходит ответ от Thread Kafka, контейнер разблокируется и возвращает ответ.
package ru.job4j.kafka.reqreply
import java.util.concurrent.FutureTask
class ReqReply(val timeout: Long) {
private val monitor = Object()
private var message = ""
private var received = false
fun send(): String {
synchronized(monitor) {
if (!received) {
try {
monitor.wait(timeout)
} catch (e: InterruptedException) {
Thread.currentThread().interrupt()
return "Interrupted while waiting"
}
}
return if (received) message else "Happened timeout $timeout"
}
}
fun receive(text: String) {
synchronized(monitor) {
received = true
message = text
monitor.notifyAll()
}
}
}
fun main() {
val reply = ReqReply(10)
val task = FutureTask({
reply.send()
})
Thread(task).start()
Thread({
Thread.sleep(500)
reply.receive("Send message")
}).start()
println(task.get())
}
Напомню, что здесь происходит:
—
wait переводит нить в режим ожидания и освобождает монитор.—
notifyAll переводит все нити, ожидающие на мониторе, в состояние RUNNING.Задание:
1. Доработайте код, приведённый выше, так, чтобы он работал с ключом
correlationId:val correlationId = UUID.randomUUID().toString()
val reply = ReqReply(10)
val task = FutureTask({
reply.send(correlationId)
})
2. Добавьте тесты (три сценария):
*
send(correlationId = 1), receive(correlationId = 1)*
send(correlationId = 1), таймаут*
send(correlationId = 1), receive(correlationId = 2), таймаут3. Загрузите код в репозиторий и оставьте ссылку на изменения.
👍6🔥1
Алго-марафон | 4 Неделя
Я продолжаю решать алгоритмы на Leetcode, но скажу, что переоценил свои усилия. За прошлую неделю решил только три задачи на динамическое программирование. Как я и говорил, они у меня вызывали сложности, потому что я в них не особо разобрался.
Сегодня перечитывал раздел о динамическом программировании в книге "Грокаем алгоритмы". Вроде бы написано довольно просто, но всё равно вызывает сложности в понимании.
Хочу предложить вам свой вариант разбора алгоритмов с динамическим программированием.
Начну с того, как определить задачу с ДП (динамическим программированием, далее по тексту):
* Имеет оптимальные подзадачи — задачу можно разбить на несколько меньших, которые решаются отдельно.
* Есть повторяющиеся вычисления — одна и та же подзадача решается несколько раз.
* Зависит от предыдущих решений — решение задачи зависит от решений предыдущих подзадач (перекрывающиеся подпоследовательности или выборы).
Рассмотрим задачу с вычислением числа Фибоначчи.
Само определение чисел Фибоначчи говорит о том, что у нас есть повторяющиеся вычисления.
Число Фибоначчи вычисляется как сумма n - 1 и n - 2.
У чисел Фибоначчи есть начальные значения: f(0) = 0, f(1) = 1, f(2) = 1.
И теперь главное правило: когда мы начинаем решать задачу на ДП, мы начинаем её с массива dp, где будут храниться промежуточные результаты.
Второй обязательный элемент — это инициализация начального состояния. В данном случае мы заполняем ячейки 0, 1, 2 изначально известными значениями.
Теперь задача сводится к заполнению массива.
https://leetcode.com/problems/fibonacci-number/description/
Попробуйте решить её на Java.
А я приведу пример на Go:
Особенность этой задачи в том, что нам изначально известна зависимость последовательности.
Посмотрите на другой пример, где тоже изначально известна зависимость последовательности:
https://leetcode.com/problems/pascals-triangle/?envType=problem-list-v2&envId=dynamic-programming.
Идем по шагам:
1. Создаем массив. В данном случае он будет двумерным.
2. Инициализируем начальные состояния.
3. Вычисляем последующие значения на основании предыдущих.
В задачах посложнее вам нужно будет самостоятельно найти закономерность последовательности:
https://leetcode.com/problems/min-cost-climbing-stairs/description/?envType=problem-list-v2&envId=dynamic-programming.
Давайте начнем с начальных этапов:
1. Создаем массив.
2. Инициализируем начальные состояния. 0 шагов — стоимость 0, 1 ступенька — cost(1), 2 ступеньки — cost(2).
А теперь нужно посчитать стоимость движения по 3 ступеньке. Она будет равна стоимости самой ступеньки плюс стоимости ступеньки, с которой мы пришли.
И тут есть нюанс: мы можем шагнуть либо с предыдущей ступеньки, либо с предпредыдущей.
Так как нам нужна минимальная стоимость, мы должны выбрать тот путь, который будет дешевле.
Этот раздел я также добавлю в наш курс: https://job4j.ru/courses/32.
Изначально его не добавил, так как на собеседованиях не встречал, но потом вспомнил, что было собеседование, где нужно было вычислить количество способов размена купюры монетами. У нас есть подобная задача в разделе "Базовый синтаксис", которая решается через жадный алгоритм, но для ответа на возможное количество способов нужно использовать решение через ДП.
Я продолжаю решать алгоритмы на Leetcode, но скажу, что переоценил свои усилия. За прошлую неделю решил только три задачи на динамическое программирование. Как я и говорил, они у меня вызывали сложности, потому что я в них не особо разобрался.
Сегодня перечитывал раздел о динамическом программировании в книге "Грокаем алгоритмы". Вроде бы написано довольно просто, но всё равно вызывает сложности в понимании.
Хочу предложить вам свой вариант разбора алгоритмов с динамическим программированием.
Начну с того, как определить задачу с ДП (динамическим программированием, далее по тексту):
* Имеет оптимальные подзадачи — задачу можно разбить на несколько меньших, которые решаются отдельно.
* Есть повторяющиеся вычисления — одна и та же подзадача решается несколько раз.
* Зависит от предыдущих решений — решение задачи зависит от решений предыдущих подзадач (перекрывающиеся подпоследовательности или выборы).
Рассмотрим задачу с вычислением числа Фибоначчи.
Само определение чисел Фибоначчи говорит о том, что у нас есть повторяющиеся вычисления.
Число Фибоначчи вычисляется как сумма n - 1 и n - 2.
У чисел Фибоначчи есть начальные значения: f(0) = 0, f(1) = 1, f(2) = 1.
И теперь главное правило: когда мы начинаем решать задачу на ДП, мы начинаем её с массива dp, где будут храниться промежуточные результаты.
Второй обязательный элемент — это инициализация начального состояния. В данном случае мы заполняем ячейки 0, 1, 2 изначально известными значениями.
Теперь задача сводится к заполнению массива.
https://leetcode.com/problems/fibonacci-number/description/
Попробуйте решить её на Java.
А я приведу пример на Go:
func fib(n int) int {
if n == 0 {
return 0
}
if n == 1 || n == 2 {
return 1
}
dp := make([]int, n + 1)
dp[0], dp[1], dp[2] = 0, 1, 1
for i := 3; i <= n; i++ {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}Особенность этой задачи в том, что нам изначально известна зависимость последовательности.
Посмотрите на другой пример, где тоже изначально известна зависимость последовательности:
https://leetcode.com/problems/pascals-triangle/?envType=problem-list-v2&envId=dynamic-programming.
Идем по шагам:
1. Создаем массив. В данном случае он будет двумерным.
2. Инициализируем начальные состояния.
3. Вычисляем последующие значения на основании предыдущих.
В задачах посложнее вам нужно будет самостоятельно найти закономерность последовательности:
https://leetcode.com/problems/min-cost-climbing-stairs/description/?envType=problem-list-v2&envId=dynamic-programming.
Давайте начнем с начальных этапов:
1. Создаем массив.
2. Инициализируем начальные состояния. 0 шагов — стоимость 0, 1 ступенька — cost(1), 2 ступеньки — cost(2).
А теперь нужно посчитать стоимость движения по 3 ступеньке. Она будет равна стоимости самой ступеньки плюс стоимости ступеньки, с которой мы пришли.
И тут есть нюанс: мы можем шагнуть либо с предыдущей ступеньки, либо с предпредыдущей.
Так как нам нужна минимальная стоимость, мы должны выбрать тот путь, который будет дешевле.
Этот раздел я также добавлю в наш курс: https://job4j.ru/courses/32.
Изначально его не добавил, так как на собеседованиях не встречал, но потом вспомнил, что было собеседование, где нужно было вычислить количество способов размена купюры монетами. У нас есть подобная задача в разделе "Базовый синтаксис", которая решается через жадный алгоритм, но для ответа на возможное количество способов нужно использовать решение через ДП.
LeetCode
Fibonacci Number - LeetCode
Can you solve this real interview question? Fibonacci Number - The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,
F(0)…
F(0)…
🔥5
🔥6
Топ 5 заблуждений о GoLang
В этой статье хотел бы рассказать о 5 заблуждениях о языке Go. Я сам попался на эти мифы, когда только начал изучать Go.
Go — это простой язык
Это самый большой миф о языке. Причем его распространяют повсеместно, и это часть маркетинга компании, причем крайне успешно. Я, например, тоже попался на это, но теперь понимаю, что Go совсем не легкий язык. С первого взгляда действительно язык выглядит компактным: базовые конструкции программирования (условия, циклы), три структуры данных (массив, слайс и карта), не до ООП, не до ФП и козырь горутины.
Но когда начинаешь писать что-то более сложное, чем задачи с LeetCode, то понимаешь, что в языке есть куча нюансов, которые необходимо учитывать, иначе код просто не будет работать. Причем на нем очень легко написать так, что понять причину ошибки будет крайне сложно.
Небольшой пример из моего проекта — антиспам-бот:
Если при создании подключения что-то пошло не так, указатель на db будет nil, а в функции defer мы пытаемся вызвать у него метод, что приведет к panic.
Go — выразительный и лаконичный
Как и многие, мне хотелось бы, чтобы для написания кода требовалось меньше усилий, а результат был бы больше. Именно поэтому несколько лет назад я начал использовать Kotlin. Если вы не пробовали писать на Kotlin, то после Java вы сразу заметите, насколько меньше нужно писать кода.
Я думал, что то же самое будет с Go. И действительно, первые программы на LeetCode выглядели компактными. Но когда я перешел к написанию своего проекта, dionea, я сразу понял, что писать придется много. Причем иногда код прямо повторяется, особенно при работе с объектами error.
Пример — функция-обертка для транзакций:
Аналогичный код на Java:
В Go нет ООП
Для меня этот пункт был самым интересным в начале моего пути в Go. Как же решаются вопросы без ООП? Как оказалось, все там есть — и ООП, и ФП, и даже процедуры.
Главный аргумент: как же ООП без наследования?
Оно тоже есть через embedded struct. Причем даже с ромбической проблемой. Но в Go есть философия: «Вот так делать не надо». Самое забавное, что в своих Java и Kotlin проектах я тоже придерживаюсь принципа замены наследования на композицию. А в учебных проектах настоятельно прошу студентов избегать использования наследования.
В этой статье хотел бы рассказать о 5 заблуждениях о языке Go. Я сам попался на эти мифы, когда только начал изучать Go.
Go — это простой язык
Это самый большой миф о языке. Причем его распространяют повсеместно, и это часть маркетинга компании, причем крайне успешно. Я, например, тоже попался на это, но теперь понимаю, что Go совсем не легкий язык. С первого взгляда действительно язык выглядит компактным: базовые конструкции программирования (условия, циклы), три структуры данных (массив, слайс и карта), не до ООП, не до ФП и козырь горутины.
Но когда начинаешь писать что-то более сложное, чем задачи с LeetCode, то понимаешь, что в языке есть куча нюансов, которые необходимо учитывать, иначе код просто не будет работать. Причем на нем очень легко написать так, что понять причину ошибки будет крайне сложно.
Небольшой пример из моего проекта — антиспам-бот:
func NewConnect(path string) (*sqlx.DB, error) {
cfg, err := load(path)
if err != nil {
return nil, &ConfigError{message: fmt.Sprintf("failed to load config from %s", path)}
}
cnn, err := sqlx.Connect(cfg.driverName, cfg.dsn)
if err != nil {
return nil, &DbError{message: fmt.Sprintf("failed to connect to %s", err.Error())}
}
return cnn, nil
}
db, err := database.NewConnect(".env")
defer func() {
if err := db.Close(); err != nil {
log.Printf("error closing db: %v", err)
}
}()
if err != nil {
log.Printf("Error connecting to database: %v", err)
return
}Если при создании подключения что-то пошло не так, указатель на db будет nil, а в функции defer мы пытаемся вызвать у него метод, что приведет к panic.
Go — выразительный и лаконичный
Как и многие, мне хотелось бы, чтобы для написания кода требовалось меньше усилий, а результат был бы больше. Именно поэтому несколько лет назад я начал использовать Kotlin. Если вы не пробовали писать на Kotlin, то после Java вы сразу заметите, насколько меньше нужно писать кода.
Я думал, что то же самое будет с Go. И действительно, первые программы на LeetCode выглядели компактными. Но когда я перешел к написанию своего проекта, dionea, я сразу понял, что писать придется много. Причем иногда код прямо повторяется, особенно при работе с объектами error.
if err != nil {
return fmt.Sprintf("occurred error %v", err)
}Пример — функция-обертка для транзакций:
func tx(db *sqlx.DB, logic func(tx *sql.Tx) error) error {
tx, err := db.Begin()
if err != nil {
return err
}
var logicErr error
defer func() {
if logicErr != nil {
rbErr := tx.Rollback()
if rbErr != nil {
log.Printf("Error during rollback: %v", rbErr)
}
}
}()
logicErr = logic(tx)
if logicErr != nil {
return logicErr
}
logicErr = tx.Commit()
if logicErr != nil {
return logicErr
}
return nil
}Аналогичный код на Java:
public <T> T tx(Function<Session, T> command) {
Session session = sf.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
T rsl = command.apply(session);
transaction.commit();
return rsl;
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
throw e;
} finally {
session.close();
}
}В Go нет ООП
Для меня этот пункт был самым интересным в начале моего пути в Go. Как же решаются вопросы без ООП? Как оказалось, все там есть — и ООП, и ФП, и даже процедуры.
Главный аргумент: как же ООП без наследования?
Оно тоже есть через embedded struct. Причем даже с ромбической проблемой. Но в Go есть философия: «Вот так делать не надо». Самое забавное, что в своих Java и Kotlin проектах я тоже придерживаюсь принципа замены наследования на композицию. А в учебных проектах настоятельно прошу студентов избегать использования наследования.
👍7
В Go нет фреймворков
Это распространённый миф, что в Go всё пишут с нуля. На самом деле здесь есть фреймворки на любой запрос. Но авторы языка говорят, что стоит задуматься, нужно ли вам брать фреймворк или достаточно нескольких функций оттуда. Поэтому обычно используют не фреймворки, а набор библиотек, который компонуют под нужды конкретного проекта.
Здесь также процветает философия «собственных велосипедов». Чем меня этот язык и привлек. Вы сразу начинаете проектировать систему под требования бизнеса, а не сначала быстро настраиваете фреймворк, а потом долго и медленно его дорабатываете под требования бизнеса. Опять же, это философия, которая освещена авторами языка.
В Go высокие зарплаты
Это тоже распространённый миф, что знание языка или стека сразу повышает зарплату. Если мы посмотрим на медианные зарплаты, то они такие же, как и у Java-разработчиков. Однако есть вакансии, где готовы платить больше, и это значительно больше, чем в Java-секторе, но там требуются специфические знания, а не просто знания стека микросервисов. То есть зарплата напрямую зависит от сектора рынка, а не от языка программирования.
Итог
Зачем копаться в этих заблуждениях о языке? Дело в том, что это позволяет понять наши мотивы, а значит, подкрепить нашу мотивацию развиваться.
Go дает возможность детально разобраться в задачах, которые мы делаем, не задумываясь. Например, аннотация @Transaction в Spring кажется простой, но если вы попробуете спроектировать подобную систему в Go, то поймете, что это крайне сложно. Go позволяет сфокусироваться на конечных технологиях: базе данных, синхронному и асинхронному общению, реализации авторизации и аутентификации, а не на особенностях конфигурирования фреймворков, как это бывает в Java.
Если вы рассматриваете язык только с точки зрения повышения зарплаты, то лучше посвятите это время прокачке целевых областей в вашем стеке и предметной области. Это принесет больше пользы и увеличение зарплаты, чем еще один язык в резюме с базовыми знаниями.
Это распространённый миф, что в Go всё пишут с нуля. На самом деле здесь есть фреймворки на любой запрос. Но авторы языка говорят, что стоит задуматься, нужно ли вам брать фреймворк или достаточно нескольких функций оттуда. Поэтому обычно используют не фреймворки, а набор библиотек, который компонуют под нужды конкретного проекта.
Здесь также процветает философия «собственных велосипедов». Чем меня этот язык и привлек. Вы сразу начинаете проектировать систему под требования бизнеса, а не сначала быстро настраиваете фреймворк, а потом долго и медленно его дорабатываете под требования бизнеса. Опять же, это философия, которая освещена авторами языка.
В Go высокие зарплаты
Это тоже распространённый миф, что знание языка или стека сразу повышает зарплату. Если мы посмотрим на медианные зарплаты, то они такие же, как и у Java-разработчиков. Однако есть вакансии, где готовы платить больше, и это значительно больше, чем в Java-секторе, но там требуются специфические знания, а не просто знания стека микросервисов. То есть зарплата напрямую зависит от сектора рынка, а не от языка программирования.
Итог
Зачем копаться в этих заблуждениях о языке? Дело в том, что это позволяет понять наши мотивы, а значит, подкрепить нашу мотивацию развиваться.
Go дает возможность детально разобраться в задачах, которые мы делаем, не задумываясь. Например, аннотация @Transaction в Spring кажется простой, но если вы попробуете спроектировать подобную систему в Go, то поймете, что это крайне сложно. Go позволяет сфокусироваться на конечных технологиях: базе данных, синхронному и асинхронному общению, реализации авторизации и аутентификации, а не на особенностях конфигурирования фреймворков, как это бывает в Java.
Если вы рассматриваете язык только с точки зрения повышения зарплаты, то лучше посвятите это время прокачке целевых областей в вашем стеке и предметной области. Это принесет больше пользы и увеличение зарплаты, чем еще один язык в резюме с базовыми знаниями.
💯9👍7🔥5
Мок-собеседование
На нашей платформе есть раздел мок-собеседования.
Некоторое время назад я хотел вынести все разделы, связанные с собеседованиями, в отдельный проект, но не учел момент с привязанностью пользователей. У нас есть привычки, и чтобы их изменить, нужно приложить много усилий. Поэтому на сайт никто не стал заходить.
Я вернул функцию мок-собеседований на основную платформу, но интерес к ней потерялся.
А сейчас, когда мы проводим эксперимент с Go, такая функция оказалась востребованной.
Напомню, как она работает.
Вы хотите обсудить какой-то раздел, например, SQL — оптимизация запросов, индексы, explain.
Создайте новое мок-собеседование. Указываете, о чём хотели бы поговорить.
Ранее я настаивал, чтобы мок-собеседование было жёстко разделено на роли: тот, кто накидывает вопросы, и тот, кто старается ответить.
В новой версии я хотел бы уйти от этих жёстких правил. То есть цель мок-собеседования — поговорить на ту или иную тему.
https://job4j.ru/interviews
На нашей платформе есть раздел мок-собеседования.
Некоторое время назад я хотел вынести все разделы, связанные с собеседованиями, в отдельный проект, но не учел момент с привязанностью пользователей. У нас есть привычки, и чтобы их изменить, нужно приложить много усилий. Поэтому на сайт никто не стал заходить.
Я вернул функцию мок-собеседований на основную платформу, но интерес к ней потерялся.
А сейчас, когда мы проводим эксперимент с Go, такая функция оказалась востребованной.
Напомню, как она работает.
Вы хотите обсудить какой-то раздел, например, SQL — оптимизация запросов, индексы, explain.
Создайте новое мок-собеседование. Указываете, о чём хотели бы поговорить.
Ранее я настаивал, чтобы мок-собеседование было жёстко разделено на роли: тот, кто накидывает вопросы, и тот, кто старается ответить.
В новой версии я хотел бы уйти от этих жёстких правил. То есть цель мок-собеседования — поговорить на ту или иную тему.
https://job4j.ru/interviews
👍14
Курс DevOps | Метрики Prometheus
Добавил уроки про метрики Prometheus.
Системные метрики приложений [#505467]
Бизнес-метрики приложений [#505468]
Вчера просматривал очередное мок-собеседование по Go. Обратил внимание, что часто спрашивают вопросы про сбор метрик.
То есть теперь рынок требует не просто написать микросервис, но также и полноценно его внедрить.
Перечислю основные метрики.
Метрики производительности
* Время отклика
* Задержки
* Пропускная способность
* Частота ошибок
Метрики здоровья приложения
* Аптайм приложения
* Жизненные циклы
* Состояние базы данных
* Метрики JVM
Метрики работы с базой данных
* Количество запросов
* Типы запросов
* Задержки запросов
Метрики приложений
* Загруженность приложений
* Использование процессора и памяти
Метрики безопасности
* Аутентификация
* Авторизация
Метрики для работы с очередями
* Обработка сообщений
* Ошибки обработки сообщений
Метрики кэширования
* Работа с кэшем
* Размер кэша
Метрики приложения в облаке
* Использование ресурсов в облаке
* Использование облачных хранилищ
Метрики для Spring Security
* Проверки авторизации
* Ошибки доступа
Метрики для Spring Actuator
* Метрики запросов в Actuator
* Статистика по здоровью и меткам
Курс: https://job4j.ru/courses/35
Добавил уроки про метрики Prometheus.
Системные метрики приложений [#505467]
Бизнес-метрики приложений [#505468]
Вчера просматривал очередное мок-собеседование по Go. Обратил внимание, что часто спрашивают вопросы про сбор метрик.
То есть теперь рынок требует не просто написать микросервис, но также и полноценно его внедрить.
Перечислю основные метрики.
Метрики производительности
* Время отклика
* Задержки
* Пропускная способность
* Частота ошибок
Метрики здоровья приложения
* Аптайм приложения
* Жизненные циклы
* Состояние базы данных
* Метрики JVM
Метрики работы с базой данных
* Количество запросов
* Типы запросов
* Задержки запросов
Метрики приложений
* Загруженность приложений
* Использование процессора и памяти
Метрики безопасности
* Аутентификация
* Авторизация
Метрики для работы с очередями
* Обработка сообщений
* Ошибки обработки сообщений
Метрики кэширования
* Работа с кэшем
* Размер кэша
Метрики приложения в облаке
* Использование ресурсов в облаке
* Использование облачных хранилищ
Метрики для Spring Security
* Проверки авторизации
* Ошибки доступа
Метрики для Spring Actuator
* Метрики запросов в Actuator
* Статистика по здоровью и меткам
Курс: https://job4j.ru/courses/35
🔥10👍3
Преза курса Go | C нуля до работы
https://job4j.ru/courses/38
В 2025 году я обратил внимание на язык Go. До этого я уже начал писать код для серверной стороны на Kotlin. У меня даже был порыв написать что-то на Python. Зачем? Для меня быть программистом — это придумывать технические решения. Чем больше у тебя в арсенале инструментов, тем проще подобрать быстрое и лучшее решение. В целом Java и языки JVM — это отличное решение, но Go предлагает нечто другое.
Скорость. Сверхбыстрая компиляция и такая же скорость выполнения самого приложения.
Исполняемые артефакты. Написал утилиту — и сразу можешь использовать её на сервере. Ничего дополнительно ставить не нужно.
Работа в многопоточной среде как с последовательным кодом. Просто и понятно.
Философия минимализма. В самом языке есть всё необходимое, а если чего-то нет — пиши сам.
На данный момент этот курс — эксперимент. Поэтому принять в нём участие можно бесплатно. Регистрируйтесь на платформе и пишите мне в Telegram @parsentev.
Этот курс мы создаём вдвоём с Михаилом. О его опыте и мыслях вы можете почитать в его Telegram-канале https://t.me/liferefactoring.
Весь курс можно разделить на две части.
Практическая часть, в которой ученики создают проект в микросервисной архитектуре. Хотелось бы акцентировать внимание на стеке. Он практически идентичен стеку в Java: Docker, Kubernetes, Kafka, Makefile, PostgreSQL, REST API, gRPC, Protobuf, Redis.
Другая часть — подготовка к собеседованиям. К сожалению, вам придётся зубрить теорию. Почему к сожалению? Потому что это не творческий процесс, но необходимый. Что сюда войдёт: обсуждение slice, map, error handling, goroutines и т. д. Не забудем и про алгоритмы.
Обучение строится по уже традиционным принципам нашей школы:
Весь материал представлен в виде уроков.
Каждый урок — это задание.
Задания проверяем мы — я и Михаил. Это code-review. Мы строгие, поэтому часто приходится переделывать ваши решения.
Разбор теории. Это подготовка к собеседованию.
В курсе около 150 уроков. Почему так много и нельзя ли быстрее?
Дело в том, что смена стека может привести к снижению уровня дохода. Чтобы этого избежать, вам нужно достичь того же уровня, что и ваш целевой язык, а ещё лучше — превзойти его. То есть если вы уже Middle, то искать работу нужно на Senior.
Даже если вы будете решать по одной задаче в день, это займёт пять месяцев. Также стоит учитывать ваши когнитивные способности — они у всех разные.
Но опять же, если у вас не такие амбиции, то, конечно, можно готовиться не так усиленно и согласиться на меньшую зарплату.
https://job4j.ru/courses/38
В 2025 году я обратил внимание на язык Go. До этого я уже начал писать код для серверной стороны на Kotlin. У меня даже был порыв написать что-то на Python. Зачем? Для меня быть программистом — это придумывать технические решения. Чем больше у тебя в арсенале инструментов, тем проще подобрать быстрое и лучшее решение. В целом Java и языки JVM — это отличное решение, но Go предлагает нечто другое.
Скорость. Сверхбыстрая компиляция и такая же скорость выполнения самого приложения.
Исполняемые артефакты. Написал утилиту — и сразу можешь использовать её на сервере. Ничего дополнительно ставить не нужно.
Работа в многопоточной среде как с последовательным кодом. Просто и понятно.
Философия минимализма. В самом языке есть всё необходимое, а если чего-то нет — пиши сам.
На данный момент этот курс — эксперимент. Поэтому принять в нём участие можно бесплатно. Регистрируйтесь на платформе и пишите мне в Telegram @parsentev.
Этот курс мы создаём вдвоём с Михаилом. О его опыте и мыслях вы можете почитать в его Telegram-канале https://t.me/liferefactoring.
Весь курс можно разделить на две части.
Практическая часть, в которой ученики создают проект в микросервисной архитектуре. Хотелось бы акцентировать внимание на стеке. Он практически идентичен стеку в Java: Docker, Kubernetes, Kafka, Makefile, PostgreSQL, REST API, gRPC, Protobuf, Redis.
Другая часть — подготовка к собеседованиям. К сожалению, вам придётся зубрить теорию. Почему к сожалению? Потому что это не творческий процесс, но необходимый. Что сюда войдёт: обсуждение slice, map, error handling, goroutines и т. д. Не забудем и про алгоритмы.
Обучение строится по уже традиционным принципам нашей школы:
Весь материал представлен в виде уроков.
Каждый урок — это задание.
Задания проверяем мы — я и Михаил. Это code-review. Мы строгие, поэтому часто приходится переделывать ваши решения.
Разбор теории. Это подготовка к собеседованию.
В курсе около 150 уроков. Почему так много и нельзя ли быстрее?
Дело в том, что смена стека может привести к снижению уровня дохода. Чтобы этого избежать, вам нужно достичь того же уровня, что и ваш целевой язык, а ещё лучше — превзойти его. То есть если вы уже Middle, то искать работу нужно на Senior.
Даже если вы будете решать по одной задаче в день, это займёт пять месяцев. Также стоит учитывать ваши когнитивные способности — они у всех разные.
Но опять же, если у вас не такие амбиции, то, конечно, можно готовиться не так усиленно и согласиться на меньшую зарплату.
Telegram
Дед Мазай
Много читаю. Много работаю. Много живу. Люблю бложить по поводу и без. В основном - о трудовых и около трудовых буднях программистов.
https://github.com/MikhailEpatko
https://www.linkedin.com/in/mikhail-epatko
https://dzen.ru/id/65edde7a1a77260ed06f79c8?
https://github.com/MikhailEpatko
https://www.linkedin.com/in/mikhail-epatko
https://dzen.ru/id/65edde7a1a77260ed06f79c8?
👍15🔥6❤1
job4j.ru - Практика. Ревью. Результат. pinned «Преза курса Go | C нуля до работы https://job4j.ru/courses/38 В 2025 году я обратил внимание на язык Go. До этого я уже начал писать код для серверной стороны на Kotlin. У меня даже был порыв написать что-то на Python. Зачем? Для меня быть программистом…»