From 9f2dfd3ed16c642a4d2c048c24cd67dda00df709 Mon Sep 17 00:00:00 2001 From: vdybysov Date: Fri, 21 Apr 2023 09:59:08 +0300 Subject: [PATCH 1/3] Create lead.md --- lead.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 lead.md diff --git a/lead.md b/lead.md new file mode 100644 index 0000000..e8cebe0 --- /dev/null +++ b/lead.md @@ -0,0 +1,48 @@ +## Как выявить причину чрезмерного использования ресурсов приложением? +Использовать Profiler, изучать heap dump, tnread dump + +## Чем отличаются `final`, `finally` и `finalize()`? +Модификатор `final`: + ++ Класс не может иметь наследников; ++ Метод не может быть переопределен в классах наследниках; ++ Поле не может изменить свое значение после инициализации; ++ Локальные переменные не могут быть изменены после присвоения им значения; ++ Параметры методов не могут изменять своё значение внутри метода. + +Оператор `finally` гарантирует, что определенный в нём участок кода будет выполнен независимо от того, какие исключения были возбуждены и перехвачены в блоке `try-catch`. + +Метод `finalize()` вызывается перед тем как сборщик мусора будет проводить удаление объекта. + +## Какая основная разница между `String`, `StringBuffer`, `StringBuilder`? +Класс `String` является неизменяемым (_immutable_) - модифицировать объект такого класса нельзя, можно лишь заменить его созданием нового экземпляра. + +Класс `StringBuffer` изменяемый - использовать `StringBuffer` следует тогда, когда необходимо часто модифицировать содержимое. + +Класс `StringBuilder` был добавлен в Java 5 и он во всем идентичен классу `StringBuffer` за исключением того, что он не синхронизирован и поэтому его методы выполняются значительно быстрей. + +## Расскажите про приведение типов. Что такое понижение и повышение типа? +Java является строго типизированным языком программирования, а это означает, то что каждое выражение и каждая переменная имеет строго определенный тип уже на момент компиляции. Однако определен механизм _приведения типов (casting)_ - способ преобразования значения переменной одного типа в значение другого типа. + +В Java существуют несколько разновидностей приведения: + ++ __Тождественное (identity)__. Преобразование выражения любого типа к точно такому же типу всегда допустимо и происходит автоматически. ++ __Расширение (повышение, upcasting) примитивного типа (widening primitive)__. Означает, что осуществляется переход от менее емкого типа к более ёмкому. Например, от типа `byte` (длина 1 байт) к типу `int` (длина 4 байта). Такие преобразование безопасны в том смысле, что новый тип всегда гарантировано вмещает в себя все данные, которые хранились в старом типе и таким образом не происходит потери данных. Этот тип приведения всегда допустим и происходит автоматически. ++ __Сужение (понижение, downcasting) примитивного типа (narrowing primitive)__. Означает, что переход осуществляется от более емкого типа к менее емкому. При таком преобразовании есть риск потерять данные. Например, если число типа `int` было больше `127`, то при приведении его к `byte` значения битов старше восьмого будут потеряны. В Java такое преобразование должно совершаться явным образом, при этом все старшие биты, не умещающиеся в новом типе, просто отбрасываются - никакого округления или других действий для получения более корректного результата не производится. ++ __Расширение объектного типа (widening reference)__. Означает неявное восходящее приведение типов или переход от более конкретного типа к менее конкретному, т.е. переход от потомка к предку. Разрешено всегда и происходит автоматически. ++ __Сужение объектного типа (narrowing reference)__. Означает нисходящее приведение, то есть приведение от предка к потомку (подтипу). Возможно только если исходная переменная является подтипом приводимого типа. При несоответствии типов в момент выполнения выбрасывается исключение `ClassCastException`. Требует явного указания типа. ++ __Преобразование к строке (to String)__. Любой тип может быть приведен к строке, т.е. к экземпляру класса `String`. ++ __Запрещенные преобразования (forbidden)__. Не все приведения между произвольными типами допустимы. Например, к запрещенным преобразованиям относятся приведения от любого ссылочного типа к примитивному и наоборот (кроме преобразования к строке). Кроме того, невозможно привести друг к другу классы, находящиеся на разных ветвях дерева наследования и т.п. + +## Что такое _Reflection_? +__Рефлексия (Reflection)__ - это механизм получения данных о программе во время её выполнения (runtime). В Java _Reflection_ осуществляется с помощью _Java Reflection API_, состоящего из классов пакетов `java.lang` и `java.lang.reflect`. + +Возможности Java Reflection API: + ++ Определение класса объекта; ++ Получение информации о модификаторах класса, полях, методах, конструкторах и суперклассах; ++ Определение интерфейсов, реализуемых классом; ++ Создание экземпляра класса; ++ Получение и установка значений полей объекта; ++ Вызов методов объекта; ++ Создание нового массива. From 24c0ccbb80bc4a642cb3a001aae908d325bfaaac Mon Sep 17 00:00:00 2001 From: vdybysov Date: Fri, 21 Apr 2023 10:36:59 +0300 Subject: [PATCH 2/3] Update lead.md --- lead.md | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/lead.md b/lead.md index e8cebe0..6be5d9c 100644 --- a/lead.md +++ b/lead.md @@ -1,5 +1,9 @@ -## Как выявить причину чрезмерного использования ресурсов приложением? -Использовать Profiler, изучать heap dump, tnread dump +## Что такое «функциональные интерфейсы»? +__Функциональный интерфейс__ - это интерфейс, который определяет только один абстрактный метод. + +Чтобы точно определить интерфейс как функциональный, добавлена аннотация `@FunctionalInterface`, работающая по принципу `@Override`. Она обозначит замысел и не даст определить второй абстрактный метод в интерфейсе. + +Интерфейс может включать сколько угодно `default` методов и при этом оставаться функциональным, потому что `default` методы - не абстрактные. ## Чем отличаются `final`, `finally` и `finalize()`? Модификатор `final`: @@ -46,3 +50,109 @@ __Рефлексия (Reflection)__ - это механизм получения + Получение и установка значений полей объекта; + Вызов методов объекта; + Создание нового массива. + +## Какие разновидности сборщиков мусора реализованы в виртуальной машине HotSpot? +Java HotSpot VM предоставляет разработчикам на выбор четыре различных сборщика мусора: + ++ __Serial (последовательный)__ — самый простой вариант для приложений с небольшим объемом данных и не требовательных к задержкам. На данный момент используется сравнительно редко, но на слабых компьютерах может быть выбран виртуальной машиной в качестве сборщика по умолчанию. Использование Serial GC включается опцией `-XX:+UseSerialGC`. ++ __Parallel (параллельный)__ — наследует подходы к сборке от последовательного сборщика, но добавляет параллелизм в некоторые операции, а также возможности по автоматической подстройке под требуемые параметры производительности. Параллельный сборщик включается опцией `-XX:+UseParallelGC`. ++ __Concurrent Mark Sweep (CMS)__ — нацелен на снижение максимальных задержек путем выполнения части работ по сборке мусора параллельно с основными потоками приложения. Подходит для работы с относительно большими объемами данных в памяти. Использование CMS GC включается опцией `-XX:+UseConcMarkSweepGC`. ++ __Garbage-First (G1)__ — создан для замены CMS, особенно в серверных приложениях, работающих на многопроцессорных серверах и оперирующих большими объемами данных. _G1_ включается опцией Java `-XX:+UseG1GC`. + +## Что такое «пул строк»? +__Пул строк__ – это набор строк, хранящийся в _Heap_. + ++ Пул строк возможен благодаря неизменяемости строк в Java и реализации идеи интернирования строк; ++ Пул строк помогает экономить память, но по этой же причине создание строки занимает больше времени; ++ Когда для создания строки используются `"`, то сначала ищется строка в пуле с таким же значением, если находится, то просто возвращается ссылка, иначе создается новая строка в пуле, а затем возвращается ссылка на неё; ++ При использовании оператора `new` создаётся новый объект `String`. Затем при помощи метода `intern()` эту строку можно поместить в пул или же получить из пула ссылку на другой объект `String` с таким же значением; ++ Пул строк является примером паттерна _«Приспособленец» (Flyweight)_. + +## В реализации класса `ArrayList` есть следующие поля: `Object[] elementData`, `int size`. Объясните, зачем хранить отдельно `size`, если всегда можно взять `elementData.length`? +Размер массива `elementData` представляет собой вместимость (capacity) `ArrayList`, которая всегда больше переменной `size` - реального количества хранимых элементов. При необходимости вместимость автоматически возрастает. + +## В чем разница между `HashMap` и `WeakHashMap`? Для чего используется `WeakHashMap`? +В Java существует 4 типа ссылок: _сильные (strong reference)_, _мягкие (SoftReference)_, _слабые (WeakReference)_ и _фантомные (PhantomReference)_. Особенности каждого типа ссылок связаны с работой Garbage Collector. Если объект можно достичь только с помощью цепочки WeakReference (то есть на него отсутствуют сильные и мягкие ссылки), то данный объект будет помечен на удаление. + +`WeakHashMap` - это структура данных, реализующая интерфейс `Map` и основанная на использовании WeakReference для хранения ключей. Таким образом, пара «ключ-значение» будет удалена из `WeakHashMap`, если на объект-ключ более не имеется сильных ссылок. + +## В чём заключается разница между IO и NIO? ++ Java IO (input-output) является потокоориентированным, а Java NIO (new/non-blocking io) – буфер-ориентированным. Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. В Java NIO данные сначала считываются в буфер, что дает больше гибкости при обработке данных. ++ Потоки ввода/вывода в Java IO являются блокирующими. Это значит, что когда в потоке выполнения вызывается `read()` или `write()` метод любого класса из пакета `java.io.*`, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого. Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания, поток выполнения может заняться чем-то другим. Тоже самое справедливо и для неблокирующего вывода. Поток выполнения может запросить запись в канал некоторых данных, но не дожидаться при этом пока они не будут полностью записаны. ++ В Java NIO имеются селекторы, которые позволяют одному потоку выполнения мониторить несколько каналов ввода. Т.е. существует возможность зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи. + +## Что такое _«сериализация»_? +__Сериализация (Serialization)__ - процесс преобразования структуры данных в линейную последовательность байтов для дальнейшей передачи или сохранения. Сериализованные объекты можно затем восстановить (десериализовать). + +В Java, согласно спецификации Java Object Serialization существует два стандартных способа сериализации: стандартная сериализация, через использование интерфейса `java.io.Serializable` и «расширенная» сериализация - `java.io.Externalizable`. + +## Дайте определение понятию «синхронизация». +Синхронизация - это процесс, который позволяет выполнять потоки параллельно. + +В Java все объекты имеют одну блокировку, благодаря которой только один поток одновременно может получить доступ к критическому коду в объекте. Такая синхронизация помогает предотвратить повреждение состояния объекта. Если поток получил блокировку, ни один другой поток не может войти в синхронизированный код, пока блокировка не будет снята. Когда поток, владеющий блокировкой, выходит из синхронизированного кода, блокировка снимается. Теперь другой поток может получить блокировку объекта и выполнить синхронизированный код. Если поток пытается получить блокировку объекта, когда другой поток владеет блокировкой, поток переходит в состояние Блокировки до тех пор, пока блокировка не снимется. + +## Что такое Semaphore? +Semaphore – это новый тип синхронизатора: семафор со счётчиком, реализующий шаблон синхронизации Семафор. Доступ управляется с помощью счётчика: изначальное значение счётчика задаётся в конструкторе при создании синхронизатора, когда поток заходит в заданный блок кода, то значение счётчика уменьшается на единицу, когда поток его покидает, то увеличивается. Если значение счётчика равно нулю, то текущий поток блокируется, пока кто-нибудь не выйдет из защищаемого блока. Semaphore используется для защиты дорогих ресурсов, которые доступны в ограниченном количестве, например подключение к базе данных в пуле. + +## Какого размера должен быть пул потоков? +Настраивая размер пула потоков, важно избежать двух ошибок: слишком мало потоков (очередь на выполнение будет расти, потребляя много памяти) или слишком много потоков (замедление работы всей систему из-за частых переключений контекста). + +Оптимальный размер пула потоков зависит от количества доступных процессоров и природы задач в рабочей очереди. На N-процессорной системе для рабочей очереди, которая будет выполнять исключительно задачи с ограничением по скорости вычислений, можно достигнуть максимального использования CPU с пулом потоков, в котором содержится N или N+1 поток. +Для задач, которые могут ждать осуществления I/O (ввода - вывода) - например, задачи, считывающей HTTP-запрос из сокета – может понадобиться увеличение размера пула свыше количества доступных процессоров, потому, что не все потоки будут работать все время. Используя профилирование, можно оценить отношение времени ожидания (`WT`) ко времени обработки (`ST`) для типичного запроса. Если назвать это соотношение `WT/ST`, то для N-процессорной системе понадобится примерно `N*(1 + WT/ST)` потоков для полной загруженности процессоров. + +Использование процессора – не единственный фактор, важный при настройке размера пула потоков. По мере возрастания пула потоков, можно столкнуться с ограничениями планировщика, доступной памяти, или других системных ресурсов, таких, как количество сокетов, дескрипторы открытого файла, или каналы связи базы данных. + +## Как выявить причину чрезмерного использования ресурсов приложением? +Использовать Profiler, изучать heap dump, tnread dump + +## Что такое _«индексы»_? Для чего их используют? В чём заключаются их преимущества и недостатки? +__Индекс (index)__ — объект базы данных, создаваемый с целью повышения производительности выборки данных. + +Наборы данных могут иметь большое количество записей, которые хранятся в произвольном порядке, и их поиск по заданному критерию путём последовательного просмотра набора данных запись за записью может занимать много времени. Индекс формируется из значений одного или нескольких полей и указателей на соответствующие записи набора данных, - таким образом, достигается значительный прирост скорости выборки из этих данных. + +Преимущества + ++ ускорение поиска и сортировки по определенному полю или набору полей. ++ обеспечение уникальности данных. + +Недостатки + ++ требование дополнительного места на диске и в оперативной памяти и чем больше/длиннее ключ, тем больше размер индекса. ++ замедление операций вставки, обновления и удаления записей, поскольку при этом приходится обновлять сами индексы. + +Индексы предпочтительней для: + ++ Поля-счетчика, чтобы в том числе избежать и повторения значений в этом поле; ++ Поля, по которому проводится сортировка данных; ++ Полей, по которым часто проводится соединение наборов данных. Поскольку в этом случае данные располагаются в порядке возрастания индекса и соединение происходит значительно быстрее; ++ Поля, которое объявлено первичным ключом (primary key); ++ Поля, в котором данные выбираются из некоторого диапазона. В этом случае как только будет найдена первая запись с нужным значением, все последующие значения будут расположены рядом. + +Использование индексов нецелесообразно для: + ++ Полей, которые редко используются в запросах; ++ Полей, которые содержат всего два или три значения, например: _мужской_, _женский пол_ или значения _«да»_, _«нет»_. + +## Что такое _«транзакция»_? +__Транзакция__ - это воздействие на базу данных, переводящее её из одного целостного состояния в другое и выражаемое в изменении данных, хранящихся в базе данных. + +[к оглавлению](#Базы-данных) + +## Назовите основные свойства транзакции. +__Атомарность (atomicity)__ гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. + +__Согласованность (consistency)__. Транзакция, достигающая своего нормального завершения и, тем самым, фиксирующая свои результаты, сохраняет согласованность базы данных. + +__Изолированность (isolation)__. Во время выполнения транзакции параллельные транзакции не должны оказывать влияние на её результат. + +__Долговечность (durability)__. Независимо от проблем на нижних уровнях (к примеру, обесточивание системы или сбои в оборудовании) изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. + +## В чем разница между операторами `GROUP BY` и `DISTINCT`? +`DISTINCT` указывает, что для вычислений используются только уникальные значения столбца. `NULL` считается как отдельное значение. +`GROUP BY` создает отдельную группу для всех возможных значений (включая значение `NULL`). + +## Для чего применяется ключевое слово `UNION`? +В языке SQL ключевое слово `UNION` применяется для объединения результатов двух SQL-запросов в единую таблицу, состоящую из схожих записей. Оба запроса должны возвращать одинаковое число столбцов и совместимые типы данных в соответствующих столбцах. Необходимо отметить, что `UNION` сам по себе не гарантирует порядок записей. Записи из второго запроса могут оказаться в начале, в конце или вообще перемешаться с записями из первого запроса. В случаях, когда требуется определенный порядок, необходимо использовать `ORDER BY`. + +## Чем интеграционное тестирование отличается от модульного? +С технологической точки зрения интеграционное тестирование является количественным развитием модульного, поскольку так же, как и модульное тестирование, оперирует интерфейсами модулей и подсистем и требует создания тестового окружения, включая заглушки на месте отсутствующих модулей. Основная разница между модульным и интеграционным тестированием состоит в целях, то есть в типах обнаруживаемых дефектов, которые, в свою очередь, определяют стратегию выбора входных данных и методов анализа. From 887c08ba9f0cd206f8ea866f889ea457384cd338 Mon Sep 17 00:00:00 2001 From: vdybysov Date: Fri, 21 Apr 2023 12:51:14 +0300 Subject: [PATCH 3/3] Update lead.md --- lead.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lead.md b/lead.md index 6be5d9c..e942a43 100644 --- a/lead.md +++ b/lead.md @@ -156,3 +156,22 @@ __Долговечность (durability)__. Независимо от проб ## Чем интеграционное тестирование отличается от модульного? С технологической точки зрения интеграционное тестирование является количественным развитием модульного, поскольку так же, как и модульное тестирование, оперирует интерфейсами модулей и подсистем и требует создания тестового окружения, включая заглушки на месте отсутствующих модулей. Основная разница между модульным и интеграционным тестированием состоит в целях, то есть в типах обнаруживаемых дефектов, которые, в свою очередь, определяют стратегию выбора входных данных и методов анализа. + +# Mongo +## Есть ли в монге ограничение на размер объекта в коллекции? +Есть, 16МБ +## Есть ли в монге уникальные или внешние ключи? +_id поле в монге всегда уникальное +Подобие внешних ключей реализовано через DBRef, но они не реализуют ограничения +## Что такое projection, для чего он нужен? +Projection позволяет разгрузить ответ запроса, исключив лишние поля (как select fields) +## Как в рамках одного запроса вернуть записи из нескольких коллекций? Как в рамках одного запроса модифицировать данные перед выдачей результата? +Использовать Aggregation pipeline, для выборки из нескольких коллекций можно использовать $lookup, для модификации результата есть множество aggregate операторов +## Какие возможности масштабирования предоставляет монга? +Горизонтальное масштабирование реализуется с помощью шардинга - разбиения коллекций между несколькими инстансами через shard key +## Можно ли сделать $lookup для шардированной коллекции? +Можно, начиная с версии 5.1 + +# ActiveMQ +## Как отфильтровать сообщения в очереди activemq? +Нужно использовать filteredDestination + selector