Java | Вопросы собесов
11.4K subscribers
34 photos
2 videos
1.13K links
Download Telegram
🤔 Где в обработке исключений может применяться конструкция с finally?

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

🚩Основная структура

try {
// Код, который может выбросить исключение
} catch (Exception e) {
// Обработка исключения
} finally {
// Этот блок выполнится всегда
}


Пример
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("file.txt");
System.out.println(fileInputStream.read());
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
} finally {
if (fileInputStream != null) {
fileInputStream.close(); // Всегда закрываем файл
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
🤔 В чем разница между HashMap и Hashtable?

1. Потокобезопасность: HashMap не потокобезопасен, а Hashtable синхронизирован.
2. Производительность: HashMap быстрее, так как не имеет синхронизации.
3. Поддержка null: HashMap допускает null как ключи, так и значения, тогда как Hashtable не позволяет использовать null в качестве ключа.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥6😁1
🤔 Какие шаги нужно выполнить для прочтения текстового файла?

Для прочтения текстового файла в Java нужно выполнить несколько шагов.

1⃣Выбор метода чтения файла
В Java есть несколько способов читать текстовые файлы:
1. Использование класса FileReader.
2. Использование BufferedReader для построчного чтения.
3. Использование java.nio.file.Files для чтения всех строк файла.
4. Применение Scanner для гибкого чтения данных.

2⃣Открытие файла
Нужно указать путь к файлу (абсолютный или относительный) и передать его в выбранный класс. Например:
FileReader reader = new FileReader("file.txt");


3⃣Чтение данных
Выберите подходящий метод для обработки содержимого файла:
- Построчное чтение.
- Чтение символов.
- Чтение всех строк сразу (например, через Files.readAllLines).

4⃣Закрытие ресурса
Для освобождения системных ресурсов после работы с файлом нужно закрыть поток. Это делается вручную или с помощью конструкции try-with-resources.

🚩Примеры реализации

Построчное чтение с BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileReadExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // Вывод строки
}
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
}
}
}


Чтение файла с помощью Files
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.List;

public class FileReadExample {
public static void main(String[] args) {
try {
List<String> lines = Files.readAllLines(Paths.get("file.txt"));
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
}
}
}


Чтение через Scanner
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileReadExample {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(new File("file.txt"))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine()); // Построчное чтение
}
} catch (FileNotFoundException e) {
System.out.println("Файл не найден: " + e.getMessage());
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍191
🤔 Какие Scopes есть у bean'ов?

1. Singleton: один экземпляр на приложение.
2. Prototype: каждый запрос создаёт новый экземпляр.
3. Request: один экземпляр на HTTP-запрос (только в веб-приложениях).
4. Session: один экземпляр на сессию (веб-приложения).
5. Application: один экземпляр на весь жизненный цикл веб-приложения.
6. WebSocket: один экземпляр на соединение WebSocket.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥52
🤔 К какой категории сущности относится Primary Key?

Primary Key (первичный ключ) в базах данных относится к категории ограничений (constraints). Это специальное ограничение, которое накладывается на столбец или группу столбцов таблицы, чтобы однозначно идентифицировать каждую строку (запись) в таблице.

🚩Основные свойства Primary Key

🟠Уникальность
Значение первичного ключа должно быть уникальным для каждой строки. Это исключает дублирование записей.
🟠Не может быть NULL
Столбец (или столбцы), определённый как Primary Key, не допускает значения NULL, так как NULL не может однозначно идентифицировать строку.
🟠Только один Primary Key на таблицу
Таблица может иметь только один первичный ключ, но он может состоять из одного столбца (простой ключ) или нескольких (составной ключ).

🚩Зачем нужен Primary Key?

Для однозначной идентификации записей в таблице.
Для создания связей между таблицами в реляционных базах данных (внешние ключи ссылаются на первичный ключ другой таблицы).
Для ускорения поиска и манипуляций с данными за счёт создания индекса на столбец первичного ключа.

🚩Пример использования Primary Key

Простой первичный ключ
CREATE TABLE Users (
user_id INT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100)
);


Составной первичный ключ
CREATE TABLE Orders (
order_id INT,
product_id INT,
PRIMARY KEY (order_id, product_id)
);


Ставь
👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍131
🤔 В чем разница между dependency injection и inversion of control?

- Inversion of Control (IoC) — принцип, по которому объект не создаёт свои зависимости, а получает их извне, обычно через IoC-контейнер.
- Dependency Injection (DI) — конкретная реализация IoC, где зависимости предоставляются через конструкторы, сеттеры или интерфейсы.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25
🤔 Назови 3 любых метода которые приходят от Object?

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

🟠`toString()`
Что делает: Возвращает строковое представление объекта.
Зачем нужен: Этот метод часто используется для вывода объектов в человекочитаемом виде, особенно для отладки или логирования.
Как работает по умолчанию: Возвращает строку, включающую имя класса и хэш-код объекта (неинтуитивно для человека).
Как переопределить: Обычно переопределяют, чтобы возвращать содержимое полей объекта в удобном формате.
class Person {
String name;
int age;

Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}

public class Main {
public static void main(String[] args) {
Person person = new Person("Анна", 25);
System.out.println(person.toString()); // Person{name='Анна', age=25}
}
}


🟠`equals(Object obj)`
Что делает: Проверяет, равны ли два объекта.
Зачем нужен: Сравнивать два объекта на логическое равенство (например, у вас есть два объекта типа Person и вы хотите понять, одинаковые ли у них значения полей).
Как работает по умолчанию: Сравнивает ссылки объектов (т.е. проверяет, указывают ли переменные на один и тот же объект в памяти).
Как переопределить: Переопределяют, чтобы сравнивать содержимое объектов (их поля).
class Person {
String name;
int age;

Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}

public class Main {
public static void main(String[] args) {
Person person1 = new Person("Анна", 25);
Person person2 = new Person("Анна", 25);
System.out.println(person1.equals(person2)); // true
}
}


🟠`hashCode()`
Что делает: Возвращает числовой хэш-код объекта.
Зачем нужен: Используется для оптимизации работы хэш-структур данных, таких как HashMap, HashSet.
Как работает по умолчанию: Генерирует уникальный хэш-код на основе местоположения объекта в памяти (что не всегда полезно).
Как переопределить: Если переопределён метод equals, обязательно переопределите hashCode, чтобы объекты, которые равны по equals, имели одинаковый хэш-код.
class Person {
String name;
int age;

Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public int hashCode() {
return name.hashCode() + age * 31; // Простая, но эффективная формула
}
}

public class Main {
public static void main(String[] args) {
Person person = new Person("Анна", 25);
System.out.println(person.hashCode()); // Например, 2084975
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1👀1
🤔 Зачем нужен Spring Framework?

Spring упрощает разработку Java-приложений за счёт:
1. Управления зависимостями через DI.
2. Поддержки модульной архитектуры.
3. Интеграции с различными технологиями (Hibernate, JPA, REST).
4. Универсальности и возможности работы с любыми Java-приложениями.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9😁1
🤔 Почему строки так часто используют в виде ключей в HashMap?

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

🟠Строки неизменяемы
Что это значит: После создания строка не может быть изменена (все операции над строками создают новый объект).
Почему это важно: Ключ в HashMap должен быть неизменяемым, потому что, если ключ изменится после его добавления, это нарушит работу хэш-таблицы. Например, HashMap больше не сможет найти объект по этому ключу.
  HashMap<String, Integer> map = new HashMap<>();
String key = "hello";
map.put(key, 1);
// key остается "hello", ничего не ломается


🟠Эффективный `hashCode` и `equals`
Что это значит: Класс String в Java имеет качественно реализованные методы hashCode() и equals(), которые оптимизированы для работы с большими наборами данных.
Почему это важно: Эти методы определяют, куда ключ попадет в HashMap (по хэш-коду) и сравнивают ключи (по equals), чтобы избежать коллизий.
Особенность: Алгоритм hashCode() у строки быстро вычисляет хэш-код на основе её символов.
  String str1 = "hello";
String str2 = "hello";
System.out.println(str1.hashCode() == str2.hashCode()); // true


🟠Простота использования
Что это значит: Строки легко создавать, читать и понимать. Они часто используются для идентификаторов (например, имён, адресов, кодов).
Почему это важно: Программистам удобно использовать строки в качестве ключей, потому что их легко интерпретировать.

🟠Универсальность
Что это значит* Строки могут представлять самые разные данные — от имён и кодов до сложных текстовых идентификаторов.
Почему это важно: Почти любой объект или данные можно однозначно представить в виде строки, что делает её универсальным кандидатом на роль ключа.

🟠Широкая поддержка
Что это значит: Почти все приложения и API Java оперируют строками.
Почему это важно: Это упрощает интеграцию строк как ключей в сложных системах.

🚩Пример использования строки в качестве ключа

import java.util.HashMap;

public class Main {
public static void main(String[] args) {
HashMap<String, Integer> ageMap = new HashMap<>();
ageMap.put("Alice", 30);
ageMap.put("Bob", 25);
ageMap.put("Charlie", 35);

// Получаем значение по строковому ключу
System.out.println("Возраст Боба: " + ageMap.get("Bob")); // 25
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
🤔 Что такое Spring контекст?

Это IoC-контейнер, который управляет жизненным циклом bean'ов и их зависимостями. Он создаёт объекты, связывает их, конфигурирует и управляет ими.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥31
🤔 Как ты можешь описать абстракцию?

Это принцип объектно-ориентированного программирования (ООП), который скрывает детали реализации объекта и показывает только его наиболее важные характеристики. Она позволяет сосредоточиться на сущности объекта, игнорируя его внутреннюю сложность.

🚩Абстракция

В Java абстракция достигается через:
Абстрактные классы
Интерфейсы

🟠Абстрактные классы
Абстрактный класс — это класс, который не может быть создан напрямую, но может содержать:
Абстрактные методы (без реализации, только сигнатуры);
Обычные методы (с реализацией).
Используется, если вы хотите описать общее поведение для группы классов, но часть поведения оставить на усмотрение конкретных подклассов.
abstract class Animal {
// Абстрактный метод — реализуется в подклассах
abstract void makeSound();

// Обычный метод
void eat() {
System.out.println("This animal eats food.");
}
}

class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Woof!");
}
}

class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow!");
}
}

public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.makeSound(); // Woof!
dog.eat(); // This animal eats food.

Animal cat = new Cat();
cat.makeSound(); // Meow!
}
}


🟠Интерфейсы
Интерфейс — это чистый контракт, который определяет набор методов, которые класс должен реализовать.
В отличие от абстрактного класса:
Интерфейс не может содержать полей (кроме static final).
Класс может реализовать несколько интерфейсов (множественное наследование).
interface Vehicle {
void start(); // метод без реализации
void stop();
}

class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car is starting.");
}

@Override
public void stop() {
System.out.println("Car is stopping.");
}
}

class Bike implements Vehicle {
@Override
public void start() {
System.out.println("Bike is starting.");
}

@Override
public void stop() {
System.out.println("Bike is stopping.");
}
}

public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start(); // Car is starting.
car.stop(); // Car is stopping.

Vehicle bike = new Bike();
bike.start(); // Bike is starting.
bike.stop(); // Bike is stopping.
}
}


🚩Почему важна абстракция?

🟠Скрытие сложностей
Программистам не нужно знать все детали реализации объекта. Они работают только с его интерфейсом.
🟠Упрощение понимания
Код становится понятным и модульным, так как мы сосредоточиваемся на важной логике.
🟠Повторное использование
Абстракция позволяет использовать один и тот же код для разных объектов.
🟠Гибкость и поддержка
Если нужно изменить реализацию, это не затронет остальную часть программы (если она работает через абстрактный контракт).

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍162🔥1
🤔 Что такое Hibernate?

Это ORM-фреймворк для работы с базами данных. Он позволяет сопоставлять объекты Java с таблицами базы данных, упрощая операции CRUD без необходимости написания SQL-кода вручную.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥21
🤔 Что знаешь про модели памяти в Java?

Модель памяти Java (Java Memory Model, JMM) определяет, как взаимодействуют потоки через память и как изменения, сделанные одним потоком, становятся видимыми для других потоков. Модель памяти Java является фундаментальной частью многопоточной среды в Java, обеспечивающей корректность и предсказуемость поведения многопоточных программ.

🚩Основные аспекты

🟠Взаимодействие потоков и памяти:

JMM определяет, как потоки взаимодействуют с переменными (данными), хранящимися в общей памяти. Каждая переменная в Java хранится в основной памяти (main memory), и потоки могут иметь локальные копии этих переменных в своих рабочих кешах.

🟠Чтение и запись переменных
Когда поток читает переменную, он может читать ее из своей локальной копии или из основной памяти. Когда поток записывает переменную, он может записывать ее в свою локальную копию или непосредственно в основную память.

🚩Гарантии JMM

🟠Последовательная согласованность (Sequential Consistency)
Последовательная согласованность гарантирует, что действия всех потоков будут выполняться в том порядке, в котором они были написаны в коде, если нет явных указаний на обратное.

🟠Видимость (Visibility)
Видимость означает, что изменения, сделанные одним потоком, становятся видимыми для других потоков. В JMM видимость изменений обеспечивается с помощью синхронизации.

🟠Произвольный порядок выполнения (Out-of-Order Execution)
JMM допускает оптимизации, такие как переупорядочивание инструкций, чтобы улучшить производительность, но гарантирует, что видимость и порядок выполнения будут сохраняться, как описано в спецификации.

public class VisibilityExample {
private static boolean flag = false;
private static int counter = 0;

public static void main(String[] args) throws InterruptedException {
Thread writer = new Thread(() -> {
counter = 42;
flag = true;
});

Thread reader = new Thread(() -> {
while (!flag) {
// Ждем пока флаг не станет true
}
System.out.println("Counter: " + counter);
});

writer.start();
reader.start();

writer.join();
reader.join();
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18
🤔 В чём разница между JDK и JRE?

- JDK (Java Development Kit): включает инструменты для разработки Java-приложений (компилятор javac, отладчики).
- JRE (Java Runtime Environment): включает только среду выполнения для запуска Java-программ (JVM и стандартные библиотеки).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥1
🤔 Используешь в работе Lambda-выражения?

Да, лямбда-выражения являются важной частью современной разработки на Java, и я активно их использую в своей работе. Лямбда-выражения помогают писать более лаконичный и выразительный код, особенно при работе с коллекциями и потоками данных. Вот несколько распространенных случаев использования лямбда-выражений в Java:

🟠Итерация по коллекциям
Использование лямбда-выражений с методом forEach позволяет компактно и удобно итерировать по элементам коллекций.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name));


🟠Фильтрация и преобразование коллекций
С использованием Stream API и лямбда-выражений можно легко фильтровать, сортировать и преобразовывать коллекции.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());

filteredNames.forEach(System.out::println); // Вывод: Alice


🟠Сортировка коллекций
Лямбда-выражения упрощают сортировку коллекций с использованием метода sort.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((name1, name2) -> name1.compareTo(name2));
names.forEach(System.out::println);


🟠Использование функциональных интерфейсов
Лямбда-выражения широко используются с функциональными интерфейсами, такими как Predicate, Function, Consumer и Supplier.
// Predicate
Predicate<String> startsWithA = s -> s.startsWith("A");
boolean result = startsWithA.test("Alice"); // true

// Function
Function<String, Integer> lengthFunction = s -> s.length();
int length = lengthFunction.apply("Hello"); // 5

// Consumer
Consumer<String> printConsumer = s -> System.out.println(s);
printConsumer.accept("Hello, World!"); // Вывод: Hello, World!

// Supplier
Supplier<String> stringSupplier = () -> "Hello, Supplier!";
String suppliedString = stringSupplier.get();
System.out.println(suppliedString); // Вывод: Hello, Supplier!


🟠Параллельные вычисления
Лямбда-выражения с использованием параллельных потоков позволяют легко выполнять параллельные вычисления.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();

System.out.println("Sum: " + sum); // Вывод: Sum: 15


🚩Пример использования в реальном проекте

Предположим, у нас есть список сотрудников, и мы хотим отфильтровать и отсортировать их по имени.
import java.util.*;
import java.util.stream.Collectors;

class Employee {
private String name;
private int age;

public Employee(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

@Override
public String toString() {
return "Employee{name='" + name + "', age=" + age + '}';
}
}

public class LambdaExample {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Alice", 30),
new Employee("Bob", 25),
new Employee("Charlie", 35),
new Employee("David", 28)
);

// Фильтрация и сортировка сотрудников по имени
List<Employee> filteredAndSorted = employees.stream()
.filter(e -> e.getAge() > 27)
.sorted(Comparator.comparing(Employee::getName))
.collect(Collectors.toList());

filteredAndSorted.forEach(System.out::println);
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍191
🤔 Чем отличается операция map от flatMap?

- map: преобразует элементы одного потока данных в другой, сохраняя структуру (например, возвращая поток потоков).
- flatMap: преобразует элементы и объединяет результаты в один поток, устраняя вложенность.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍7
🤔 Докажи CAP теорему

CAP-теорема (Consistency, Availability, Partition Tolerance) утверждает, что в распределенной системе невозможно одновременно обеспечить три свойства:

🟠Consistency (Согласованность)
все узлы видят одни и те же данные в один момент времени.
🟠Availability (Доступность)
каждый запрос получает ответ, даже если некоторые узлы вышли из строя.
🟠Partition Tolerance (Устойчивость к разделению сети)
система продолжает работать, даже если сеть разделилась на изолированные части.

🚩Доказательство

Рассмотрим сценарий с распределенной системой, состоящей из двух узлов (A и B), которые могут обмениваться данными.

🟠Предположим, что произошел сетевой раздел (Partition Tolerance, P)
узлы A и B больше не могут обмениваться данными.
Теперь у нас есть выбор
🟠Обеспечить согласованность (C)
это значит, что данные на A и B должны оставаться идентичными. Однако, так как они не могут обмениваться данными, запросы к B не могут быть обработаны до восстановления связи (нарушается доступность).
🟠Обеспечить доступность (A)
это значит, что оба узла должны продолжать отвечать на запросы. Однако, так как они не могут синхронизироваться, данные на A и B могут отличаться (нарушается согласованность). Так как разделение сети (P) может произойти в реальных условиях, система вынуждена выбирать между C и A. Таким образом, невозможно одновременно обеспечить все три свойства (C, A, P).

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🤔3🤯3
🤔 Что такое инкапсуляция?

Это принцип ООП, который скрывает реализацию объекта и предоставляет доступ только к необходимой информации через методы. Она обеспечивает контроль доступа к данным и защиту от некорректного использования.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19👀3🤔1
🤔 Что такое Java Server Pages JSP?

Java Server Pages (JSP) — это технология для создания динамических веб-страниц с использованием Java. JSP позволяет смешивать HTML с Java-кодом для генерации динамического контента на сервере.

🚩Плюсы:

Интеграция с Java:
Вставка Java-кода в HTML-страницы.

Теги JSP:
Скриплеты: <% ... %>
Выражения: <%= ... %>
Директивы: <%@ ... %>
Декларации: <%! ... %>

JavaBeans:
Поддержка использования JavaBeans для разделения логики и представления.

Пользовательские теги:
Расширение функциональности через собственные теги.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Когда говорят, что Java слишком простой язык, на сцену выходит канал Java Learning

Здесь легко научиться:

▪️ Разрабатывать высоконагруженные серверные приложения
▪️ Управлять сложными базами данных
▪️ Организовывать эффективную многопоточную обработку данных
▪️ Проходить технические собеседования в ведущие IT-компании

Самый необычный канал про Java, подписывайся@Java_per_month
Please open Telegram to view this post
VIEW IN TELEGRAM
1