MiddleJava Developer > Java Core > ООП
Короткий ответ Абстрактный класс — это класс, который нельзя инстанцировать: он задаёт шаблон наследникам и может содержать абстрактные методы, обычные методы с реализацией, поля, конструкторы и статические члены. Интерфейс описывает контракт поведения: до Java 8 в нём были только абстрактные методы и константы, с Java 8 появились default- и static-методы, с Java 9 — private-методы. Как это работает подробнее Оба механизма описывают абстракции, но решают разные задачи. Класс может наследовать только один абстрактный класс, зато реализует сколько угодно интерфейсов — это частично компенсирует отсутствие множественного наследования. На практике их часто комбинируют: класс наследует абстрактную базу и дополнительно реализует один или несколько интерфейсов. Состояние — абстрактный класс может иметь поля и конструкторы (вызываются через super()); в интерфейсе только константы public static final. Методы — в абстрактном классе абстрактные и обычные методы; в интерфейсе с Java 8 — default, static, а с Java 9 — priva
abstract-classinterface
JuniorJava Developer > Java Core > Spring
Короткий ответ @Controller — MVC-контроллер классических веб-приложений: его методы возвращают имя представления (JSP или шаблон Thymeleaf), в которое передаётся модель. @RestController — специализированная аннотация для REST-сервисов: комбинация @Controller + @ResponseBody, поэтому методы сразу возвращают данные. Как это работает подробнее Методы @RestController возвращают данные (как правило, JSON или XML), которые автоматически сериализуются в тело ответа с помощью HttpMessageConverter (например, Jackson). Ни @ResponseBody на каждом методе, ни view resolver для этого не нужны. Ключевое отличие: @Controller возвращает представление (view), а @RestController — данные (JSON/XML). Сфера применения: @Controller — классические веб-приложения на Spring MVC, @RestController — REST API и микросервисы. Возврат данных из @Controller: чтобы отдать JSON или XML, к методу нужно добавить @ResponseBody. Пример кода Что использовать на практике Для REST API и микросервисов всегда используйте @RestController — в Spring Boot
javamvc
MiddleJava Developer > Java Core > Multithreading
Короткий ответ wait() — метод класса Object, а sleep() — статический метод класса Thread. wait() служит для межпоточной коммуникации, вызывается только из синхронизированного кода и при вызове освобождает монитор объекта. sleep() просто приостанавливает текущий поток на заданное время и не освобождает удерживаемые блокировки. Как это работает подробнее wait() вне синхронизированного метода или блока бросит IllegalMonitorStateException. Поток переходит в ожидание, пока другой поток не вызовет notify()/notifyAll() на том же объекте либо не истечёт указанный таймаут; без таймаута ожидание может длиться «вечно». sleep() можно вызывать где угодно, он всегда принимает время задержки и удобен для имитации пауз. Пара wait()/notify() — классический механизм схемы «производитель — потребитель» для ожидания наступления условия. Оба метода бросают проверяемое InterruptedException, которое нужно обрабатывать. Пример кода Что использовать на практике Используй wait()/notifyAll(), когда поток должен ждать наступления услови
javamultithreading
MiddleJava Developer > Java Core > Collections
Короткий ответ Comparable задаёт «естественный» порядок самого класса: класс реализует интерфейс и метод compareTo(Object o), в котором зашито правило «я больше или меньше другого». Так устроены стандартные классы — String, Integer, Date. Comparator — отдельный класс или лямбда с методом compare(a, b), который не требует изменять сравниваемый класс, поэтому для одного типа можно завести много стратегий сортировки. Как это работает подробнее Отсортировать коллекцию можно через Collections.sort(...) или list.sort(...): если передан только список, элементы должны реализовывать Comparable; если нужен особый порядок — вторым аргументом передаётся Comparator. У Comparator есть удобные дефолтные методы comparing(...), thenComparing(...), reversed(), из которых собирается составная сортировка. Comparable: один естественный порядок в самом классе — например, по id. Comparator: порядок зависит от контекста, или класс чужой и менять его нельзя. Пример кода Что использовать на практике Comparable берите, когда у класса е
collectionscomparable
MiddleJava Developer > Java Core > Collections
Короткий ответ Fail-fast итератор работает с самой коллекцией и при любом структурном изменении (добавление или удаление элементов), выполненном не через сам итератор, немедленно выбрасывает ConcurrentModificationException. Fail-safe — точнее, слабо согласованные (weakly consistent) итераторы из java.util.concurrent — не бросают исключение при параллельных изменениях, но не гарантируют, что увидят изменения, сделанные после создания итератора. Как это работает подробнее Механизм fail-fast реализован через счётчик модификаций modCount: итератор запоминает его при создании и сравнивает при каждом вызове next(); если значения разошлись — коллекция менялась «на стороне» — итератор «быстро падает» с исключением. Так ведут себя коллекции пакета java.util: ArrayList, HashMap, LinkedList. Fail-safe итераторы либо проходят по копии коллекции, либо устроены так, что не бросают исключение; плата — дополнительные расходы памяти на копирование или менее строгие данные. Примеры fail-safe: итераторы ConcurrentHashMap, CopyO
collectionsconcurrentmodificationexception
MiddlePython Developer > Основы Python > Генераторы и итераторы
Короткий ответ return завершает функцию и передаёт вызывающему коду единственное значение, а yield лишь приостанавливает функцию, возвращает промежуточный результат и сохраняет состояние. Функция с yield становится генераторной и может отдавать значения многократно. Как это работает подробнее return. Функция прекращает работу, возвращает одно значение, а её локальные переменные уничтожаются; при повторном вызове она стартует заново. yield. Функция замирает, возвращает промежуточный результат и сохраняет состояние — локальные переменные и позицию исполнения. Продолжение. Код после yield выполняется при последующем обращении, а функция продолжается с того же места. Область применения. yield используют для порождения последовательностей и потоковой обработки без построения всей коллекции, return — для единственного финального результата. Пример кода Что использовать на практике Один результат. Если функция вычисляет единственное значение, используй return. Серия значений. Когда нужно отдавать последовательность
functionsgenerators
JuniorJava Developer > Java Core > Исключения
Короткий ответ throw — оператор, который в точке выполнения кода непосредственно выбрасывает исключение: после него указывается объект-исключение, например throw new IllegalArgumentException(). throws — объявление в сигнатуре метода о том, какие исключения метод может выбросить: void read() throws IOException. Первый пишется в теле метода, второй — в его сигнатуре. Как это работает подробнее throw используется внутри тела метода. Бросить можно только объект класса, наследующего Throwable. Один вызов throw бросает ровно одно исключение, после чего управление уходит на поиск подходящего catch или выше по стеку. throws стоит в сигнатуре и сообщает компилятору и вызывающему коду, что метод может выбросить перечисленные исключения. Если метод способен выбросить checked-исключение, он обязан либо перехватить его в try-catch, либо объявить в throws — иначе код не скомпилируется. Для unchecked-исключений (RuntimeException и Error) объявление не обязательно. throw работает с объектом исключения и пишется в теле метода
checked-exceptionsexceptions
JuniorJava Developer > Java Core > Core Java
Константа объявляется с модификатором final: её значение нельзя переприсвоить после инициализации.
Basics
MiddlePython Developer > Основы Python > Основы Python
Короткий ответ Мелкое копирование создаёт новый объект верхнего уровня, но не копирует вложенные объекты: их изменения видны в оригинале. Глубокое копирование рекурсивно дублирует все вложенные объекты и даёт полностью независимую копию. А простое присваивание копией не является вовсе — оно лишь добавляет ссылку. Как это работает подробнее Разница проявляется при работе с вложенными структурами: списками списков, словарями со списками и объектами, содержащими другие объекты. Присваивание. Запись b = a не создаёт копию: обе переменные ссылаются на один и тот же объект, поэтому изменения видны через обе. Мелкая копия. Функция copy.copy() создаёт новый объект верхнего уровня, но копирует только ссылки на вложенные объекты, которые остаются разделяемыми. Глубокая копия. Функция copy.deepcopy() рекурсивно дублирует вложенные объекты, создавая полностью независимую структуру. Плоские структуры. Для структур только из неизменяемых значений мелкая и глубокая копия ведут себя практически одинаково. Пример кода Что исп
copy-moduledeep-copy
MiddleJava Developer > Java Core > Multithreading
sleep() приостанавливает поток и не освобождает монитор, wait() освобождает монитор и ждет notify().
Multithreading