Библиотека программиста | программирование, кодинг, разработка
85.5K subscribers
3.13K photos
147 videos
88 files
6.35K links
Все самое полезное для программиста в одном канале.

Список наших каналов: https://tttttt.me/proglibrary/9197
Учиться у нас: https://proglib.io/w/a32a0d94

Обратная связь: @proglibrary_feedback_bot

По рекламе: @proglib_adv
Прайс: @proglib_advertising
Download Telegram
В функциональных языках это позволяет создавать структуры вроде бесконечных списков, которые в обычных условиях невозможны в императивных языках программирования, где очередность команд имеет значение.
🗄Monoid (моноид) — объект с функцией, которая «комбинирует» объект с другим объектом того же типа.
🗄Monad (монада) — объект с функциями of и chain. chain похож на map, но он производит разложение вложенных объектов в результате.
🗄Comonad (комонада) — объект с функциями extract и extend. Extract берет значение из функтора. Extend выполняет функцию на комонаде. Функция должна вернуть тот же тип, что комонада.
🗄Applicative Functor (аппликативный функтор) — объект с функцией ap. ap применяет функцию в объекте к значению в другом объекте того же типа. Это полезно, когда есть два объекта, и нужно применить бинарную операцию на их содержимом.
🗄Morphism (морфизм) — функция трансформации.
🗄Endomorphism (эндоморфизм) — функция, у которой ввод и вывод — одного типа.
🗄Isomorphism (изоморфизм) — пара структурных трансформаций между двумя типами объектов без потери данных. Например, двумерные координаты можно хранить в массиве [2,3] или объекте {x: 2, y: 3}.
🗄Setoid — объект, у которого есть функция equals, которую можно использовать для сравнения объектов одного типа.
🗄Semigroup (полугруппа) — объект с функцией concat, которая комбинирует его с другим объектом того же типа.
🗄Foldable — объект с функцией reduce, которая трансформирует объект в другой тип.
🗄Type Signatures (сигнатуры типа) — определяет входящие и возвращаемые типы для функции, иногда включая число аргументов, типы аргументов и порядок аргументов, содержащихся в функции.
🗄Option (опцион) — тип-объединение с двумя случаями: Some и None. Полезно для композиции функций, которые могут не возвращать значения.

Источник:

🧵Читать в Твиттере
🧵Читать в Thread Reader App (если Твиттер не открывается)

#вопросы_с_собесов #medium
Please open Telegram to view this post
VIEW IN TELEGRAM
Если на собесе спрашивают про Docker, жди вопрос про разницу между виртуализацией и контейнеризацией!

По-хорошему их сравнивать нельзя, т. к. у них разное предназначение. Смотрите сами 👇

📌 Контейнеры предоставляют изолированную среду для запуска приложения, при этом все пользовательское пространство явно выделено для приложения.

Любые изменения, сделанные внутри контейнера, никогда не отражаются на хост-машине или на других контейнерах.

Контейнеры — это абстракция прикладного уровня. Каждый контейнер — отдельное приложение.

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

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

#вопросы_с_собесов #ease
Помните затрагивали основные концепции ООП? Так вот, между объектами есть ещё несколько видов отношений, о которых важно знать. Разберем их кратко:

🔸Реализация: класс А определяет методы, объявленные интерфейсом B. Объекты А можно рассматривать через интерфейс B. Класс А зависит от B.
🔸Наследование: класс А наследует интерфейс и реализацию класса B, но может ее переопределить. Объекты А можно рассматривать через интерфейс класса B. Класс А зависит от B.
🔸Зависимость: класс А могут затронуть изменения в классе B.
🔸Агрегация: Объект А знает об объекте B и состоит из него. Класс А зависит от B.
🔸Ассоциация: Объект А знает об объекте B. Класс А зависит от B.
🔸Композиция: Объект А знает об объекте B, состоит из него и управляет его жизненным циклом. Класс А зависит от B.

#вопросы_с_собесов #easy
Redis — опенсорсное быстрое хранилище данных в памяти класса NoSQL, работающее со структурами данных типа «ключ — значение».

Redis используется в качестве базы данных, кэша, брокера сообщений, очереди и нескольких других юзкейсов ☝️

#вопросы_с_собесов
Предположим, что вы перешли в свой проект, начали работать над несколькими файлами и, возможно, добавили в индекс Git изменения одного из них. Если вы выполните git status, то увидите ваше изменённое состояние.

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

Команда git stash или git stash push позволяет на время «сдать в архив» (отложить, припрятать) эти изменения в выделенное для этого специальное хранилище.

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

🔸 Посмотреть список отложенных изменений: git stash list
🔸 Применить только что отложенные изменения: git stash apply или git stash apply stash@{2}

#вопросы_с_собесов #easy
Представьте, что вы начали работать над новой фичей в отдельной ветке, после чего другой участник команды добавляет новые коммиты в главную ветку main. Возникает история форков, знакомая каждому, кто использовал Git для совместной работы.

А теперь предположим, что новые коммиты в ветке main затрагивают фичу, над которой вы работаете. Каким способом можно внести изменения из одной ветки в другую?

В Git есть два способа сделать это: слияние или перебазирование.

📌
Способ слияния (merge)
> git checkout feature
> git merge main

➡️или в одну строку: git merge feature main

Эта команда создает в ветке feature новый «коммит слияния», связывающий истории обеих веток. Это отличная неразрушающая операция, при которой существующие ветки никак не изменяются.

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

Если работа в главной ветке main ведется активно, история вашей ветки feature быстро засорится.

📌
Способ перебазирования (rebase)

Вместо слияния можно выполнить перебазирование ветки feature на ветку main
с помощью следующих команд:

> git checkout feature
> git rebase main

В результате вся ветка feature окажется поверх ветки main, включая в
себя все новые коммиты в ветке main.

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

☑️
Главное преимущество rebase — более чистая история проекта. Эта операция устраняет ненужные коммиты слияния, необходимые для git merge.

#вопросы_с_собесов #easy
Основная задача Git — гарантировать, что вы не потеряете внесенные изменения. Но эта система также предназначена для предоставления вам полного контроля над процессом разработки. Среди прочего вы сами определяете то, как выглядит история вашего проекта. Такая свобода создает и вероятность потери коммитов.

👉 Какие команды предоставляет Git для перезаписи истории?

📌 Git предоставляет несколько способов изменения истории и отмены изменений:

✔️Используйте команду git commit --amend (--no-edit/-m "comment") для изменения последнего коммита
✔️Используйте команду git rebase для объединения коммитов и изменения истории ветки (git rebase -i даст вам более точный контроль над изменениями истории)
✔️Если вы завершили перебазирование, а затем решили, что полученный результат это не то, что вам нужно — воспользуйтесь командой git reflog, чтобы восстановить предыдущую версию вашей ветки

#вопросы_с_собесов #устрой_деплой
#вопросы_с_собесов

В чем разница между Docker и Kubernetes?


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

🔸Kubernetes (K8s) — платформа для автоматизации развёртывания, масштабирования и управления контейнеризированными приложениями.

📌
Чем они отличаются друг от друга?

Docker работает на уровне отдельного контейнера на одном хосте операционной системы.

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

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

📝 Другими словами, Docker фокусируется на контейнеризации и запуске контейнеров на отдельных хостах, в то время как Kubernetes специализируется на управлении и оркестровке контейнеров в масштабе кластера хостов.

🔗
Источник
Please open Telegram to view this post
VIEW IN TELEGRAM
#вопросы_с_собесов #easy

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

В Git есть две категории больших репозиториев:
1️⃣В них накапливается очень длинная история
2️⃣В них находятся огромные двоичные файлы, которые нужно отслеживать и сопоставлять с кодом

🤷‍♂️А иногда бывает и то, и другое.

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

📌 Клонирование репозиториев с очень длинной историей

1️⃣Простое решение: поверхностное клонирование git

> git clone --depth [глубина] [remote-url]

2️⃣Ювелирная точность

> git filter-branch --tree-filter 'rm -rf [/путь/к/папке/ненужных/файлов]'

3️⃣Альтернатива git shallow-clone: клонирование только одной ветки

> git clone [remote_url] --branch [имя_ветки] --single-branch [папка]

📌 Управление репозиториями с огромными двоичными файлами

4️⃣Решение для больших деревьев папок: git sparse-checkout

5️⃣Решение для управления обновлением больших файлов: подмодуль Git. Подмодули позволяют вам сохранить один Git-репозиторий, как подкаталог другого Git-репозитория. Это даёт вам возможность клонировать в ваш проект другой репозиторий, но коммиты при этом хранить отдельно.

💡А еще можно забыть все, что вы прочитали выше, и воспользоваться Git LFS. Это решение, разработанное Atlassian совместно с GitHub в 2015 году.

Расширение Git LFS позволяет хранить в репозитории не сами большие файлы, а только указатели на них. Сами файлы хранятся на удаленном сервере.
Please open Telegram to view this post
VIEW IN TELEGRAM
#вопросы_с_собесов

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

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

💡Хуки разделяются на серверные и клиентские. Если хуки на стороне клиента запускаются слиянием или созданием коммита, то на стороне сервера они инициируются сетевыми операциями, такими как получение отправленного коммита.

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

💡Все хуки Git представляют собой обыкновенные скрипты, которые Git исполняет в ответ на определенные события в репозитории.

💡Хуки находятся в каталоге .git/hooks каждого репозитория. Git автоматически заполняет этот каталог примерами скриптов при инициализации репозитория.

💡Для подключения собственного скрипта достаточно задать ему соответствующее имя (убрать .sample) и сделать исполняемым.

📝Для клиента существует множество различных хуков: уровня коммита, на основе e-mail и другие.

📝В дополнение к хукам на стороне клиента, вы можете использовать несколько важных хуков на сервере для вашего проекта. Эти скрипты выполняются до и после отправки на сервер.
Please open Telegram to view this post
VIEW IN TELEGRAM
#вопросы_с_собесов

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

💬Каким инструментом Git можно воспользоваться, чтобы быстро выяснить, из-за какого конкретно коммита возникла данная проблема?

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

🔸Это утилита для поиска коммита, в котором впервые проявился баг или проблема с помощью автоматического бинарного поиска.

🔸Последовательность действий следующая: запускаем процесса поиска, затем указываем Git на коммть, который сломан, после чего указываем, когда было последнее известное рабочее состояние.

> git bisect start
> git bisect bad
> git bisect [good_commit]

1⃣Git автоматически переключит нас на коммит, который находится посередине между хорошим и плохим коммитами. Продолжаем👇

2⃣Запускаем тесты и проверяем наличие проблемы в этом коммите. Пусть в данном коммите проблема не выявлена. Сообщаем об этом Git с помощью git bisect good и продолжаем дальше👇

3⃣Мы оказались на другом коммите, расположенном посредине между только что протестированным и плохим коммитами. Снова выполняем тесты и обнаруживаем, что текущий коммит сломан, и сообщаем об этом Git с помощью команды git bisect bad👇

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

4⃣После завершения поиска выполняем git bisect reset, чтобы вернуться к изначальной ветке и завершить процесс bisect.

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

Начальные вопросы могут звучать так:

📌«Для чего предназначена нормализация?»,
📌«Какие вы знаете формы нормализации и для чего они предназначены?».

Если бы вам задали такие вопросы на собеседовании, как бы вы ответили?👇

#вопросы_с_собесов
Please open Telegram to view this post
VIEW IN TELEGRAM
🤨 В контексте вопросов про алгоритмы на собеседовании интервьюер может спросить вас среди прочего что-то вроде:

📌«Что такое вычислительная сложность алгоритмов и как её оценить?»,
📌«Что такое О-нотация?» или подобные вопросы, смысл которых не сильно отличается.

Если бы вам задали такие вопросы на собеседовании, как бы вы ответили?👇

#вопросы_с_собесов
Please open Telegram to view this post
VIEW IN TELEGRAM
💬Чем отличаются статически типизированные языки от динамически типизированных?

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

💡Статическая: тип каждой переменной определяется во время компиляции (Java, C#, C++). То есть типы всех переменных должны быть известны до выполнения программы. Преимущества: более раннее обнаружение ошибок (компилятор может обнаружить типовые ошибки) и улучшение производительности (определение типов происходит на этапе компиляции).

💡Динамическая: типы переменных определяются во время выполнения программы (Python, Ruby, JavaScript). То есть переменные могут принимать различные типы данных в разное время во время выполнения. Основные преимущества — гибкость и более короткий код.

👉 Подробнее

#вопросы_с_собесов
This media is not supported in your browser
VIEW IN TELEGRAM
🔂 4 наиболее часто используемых типов очередей на одной диаграмме: наглядная иллюстрация от ByteByteGo (Alex Xu)

1️⃣Простая очередь FIFO. Следует принципу First In First Out — первым пришел, первым ушел. Все новые элементы добавляются в конец очереди. Когда элемент удаляется из очереди, удаляется элемент, который находится в начале очереди, то есть добавленный первым.

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

2️⃣Круговая очередь или кольцевой буфер. Ее последний элемент связан с первым элементом. Вставка происходит в начале очереди, а удаление — в конце.

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

3️⃣Очередь с приоритетами. Каждый элемент имеет определенный приоритет, и элементы обрабатываются в порядке их приоритета, а не в порядке их добавления.

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

4️⃣ Двухсторонняя очередь. Вставка и удаление могут происходить как в начале, так и в конце очереди. Двухсторонняя очередь поддерживает как FIFO, так и LIFO (Last In First Out — последним пришел, первым ушел), поэтому мы можем использовать ее для реализации структуры данных стека.

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

#вопросы_с_собесов
Please open Telegram to view this post
VIEW IN TELEGRAM
🔂 Наиболее популярные стратегии снижения рисков деплоя или обновления сервисов: наглядная демонстрация от ByteByteGo (Alex Xu)

🔧 Мульти-сервисный деплой: одновременное обновление нескольких сервисов. Просто в реализации, но сложно управлять зависимостями и откатывать изменения.
🔧 Сине-зеленый деплой: подразумевает два одинаковых среды — стейджинг (синяя) и продакшен (зеленая). После тестирования в стейджинге, пользователи переключаются на нее, и она становится продакшеном. Удобна для отката, но может быть «дорогостоящей».
🔧 Канареечный деплой: постепенное обновление сервисов для небольших групп пользователей. Более экономична и легко откатывается, но требует тестирования в продакшене и мониторинга.
🔧 A/B тестирование: разные версии сервисов работают в продакшене для разных групп пользователей. Эффективно для тестирования новых функций, но требует контроля, чтобы избежать случайного деплоя функций.

#вопросы_с_собесов
This media is not supported in your browser
VIEW IN TELEGRAM
🗄 ACID в контексте транзакции базы данных: наглядная демонстрация от ByteByteGo (Alex Xu)

🔹 Atomicity (атомарность) гарантирует, что каждая транзакция будет выполнена полностью или не будет выполнена совсем. Не допускаются промежуточные состояния.
🔹 Consistency (согласованность). Благодаря тому, что транзакция не допускает промежуточных результатов, БД остается консистентной. Есть такое определение транзакции: «Упорядоченное множество операций, переводящих базу данных из одного согласованного состояния в другое». То есть до выполнения операции и после БД остается консистентной (согласованной).
🔹 Isolation (изолированность). Во время выполнения транзакции параллельные транзакции не должны оказывать влияния на ее результат.
🔹 Durability (надежность). Если пользователь получил подтверждение от системы о выполнении транзакции, он может быть уверен, что сделанные им изменения не будут отменены из-за какого-либо сбоя.

#вопросы_с_собесов
💬 Что такое транзакции и какие бывают уровни изоляции транзакций в контексте баз данных?

👉 Транзакции — это последовательность операций, которые либо полностью выполняются, либо не выполняются вовсе, обеспечивая свойства ACID (атомарность, согласованность, изоляция, долговечность).

👉 Выбор уровня изоляции зависит от требований к консистентности данных и допустимости параллелизма транзакций.

📌 Проблемы параллельного доступа с использованием транзакций:

🔸 Потерянное обновление (англ. lost update) — при одновременном изменении одного блока данных разными транзакциями теряются все изменения, кроме последнего.
🔸 «Грязное» чтение (англ. dirty read) — чтение данных, добавленных или изменённых транзакцией, которая впоследствии не подтвердится (откатится).
🔸 Неповторяющееся чтение (англ. non-repeatable read) — при повторном чтении в рамках одной транзакции ранее прочитанные данные оказываются изменёнными.
🔸 Фантомное чтение (англ. phantom reads) — одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям.

📌 Уровни изоляции транзакций определяют, как данные видны другим транзакциям и как они защищены от одновременных изменений. Уровни включают:

1. Read uncommitted: наименьший уровень изоляции, позволяет читать незафиксированные данные, что может привести «грязному» чтению.
2. Read committed: позволяет избежать «грязного» чтения, но не устраняет феномены неповторяемого чтения и фантомного чтения.
3. Repeatable read: предотвращает неповторяемые чтения, но может не предотвратить фантомное чтение.
4. Serializable: самый высокий уровень изоляции, который предотвращает фантомное чтение, но может снижать производительность из-за блокировок.

#вопросы_с_собесов
💬 Что такое индексы и составные индексы в контексте баз данных (например, MySQL)? Для чего используется инструкция EXPLAIN?

Индексы являются инструментом для оптимизации SQL-запросов. Они ускоряют доступ к данным, сокращая количество операций чтения и сравнения.

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

🔸 Составные индексы — это индексы, построенные на нескольких колонках. Они полезны для запросов, которые используют несколько колонок в условиях WHERE, JOIN или ORDER BY. Порядок колонок в составном индексе важен, так как он влияет на эффективность индекса.

🔸 EXPLAIN в MySQL используется для анализа того, как выполняются SQL-запросы. Она показывает, какие индексы используются, сколько строк должно быть прочитано, и помогает определить, как можно оптимизировать запросы.

👉 Подробнее

#вопросы_с_собесов