☕🧵 Введение в многопоточность в Java. Часть 2. Жизненный цикл потоков, Thread.join() и потоки-демоны
https://proglib.io/p/vvedenie-v-mnogopotochnost-v-java-chast-2-zhiznennyy-cikl-potokov-thread-join-i-potoki-demony-2022-11-30
@javatg
https://proglib.io/p/vvedenie-v-mnogopotochnost-v-java-chast-2-zhiznennyy-cikl-potokov-thread-join-i-potoki-demony-2022-11-30
@javatg
Библиотека программиста
☕🧵 Введение в многопоточность в Java. Часть 2. Жизненный цикл потоков, Thread.join() и потоки-демоны
В этой части узнаем, какие состояния проходят потоки в своем жизненном цикле, что такое ожидание потоков и что такое потоки-демоны.
Ответ:
В этой программе мы инициализировали массив с 10 случайными элементами, из которых мы собираемся найти второе по величине число. Далее мы создали две целочисленные переменные, которым будем присваивать значения двух целых чисел из массива - самого большого и второго по величине. Обе переменные изначально получают значения первого по индексу элемента массива. Затем мы выводим на экран все элементы, используя цикл for.
Дальнейшая логика работы программы в том, чтобы используя цикл for обойти массив.
При обходе, если элемент массива с текущим индексом больше, чем значение, хранящееся в переменной biggest, тогда переменной secondBiggest присваиваем значение, хранящееся в biggest, а переменной biggest – новое наибольшее значение в соответствии со значением текущего элемента массива. Опять же, если элемент по текущему индексу больше, чем secondBiggest, то присвойте secondBiggest значение этого элемента.
Это будет повторяться для каждой итерации и, в конечном итоге, после завершения обхода массива в цикле вы получите элементы наибольший и второй по величине элементы массива в переменных biggest и secondBiggest соответственно.
public class SixteenthTask {
public static void main(String[] args)
{
int numbersArray[] = { 10, 15, 32, 100, 16, 11, 98, 36, 95, 33 };
int biggest= numbersArray[0];
int secondBiggest = numbersArray[0];
System.out.println("Полученный массив: ");
for (int i = 0; i < numbersArray.length; i++)
{
System.out.print(numbersArray[i] + "\t");
}
for (int i = 0; i < numbersArray.length; i++)
{
if (numbersArray[i] > biggest)
{
secondBiggest = biggest;
biggest = numbersArray[i];
}
else if (numbersArray[i] > secondBiggest && numbersArray[i] != biggest)
{
secondBiggest = numbersArray[i];
}
}
System.out.println("\nВторое по величине число:" + secondBiggest);
}
}
На экране получим:
Полученный массив:
10 15 32 100 16 11 98 36 95 33
Второе по величине число: 98
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
Это простая программа, в которой у нас есть строковая переменная st1.
Другая строковая переменная st2 инициализируется с помощью метода replaceAll, который является встроенным методом для удаления n числа пробелов. В итоге мы выводим на экран st2, которая уже не содержит пробелов.
public class EighteenthTask
{
public static void main(String[] args)
{
String st1 = "Мы готовимся к интервью на вакансию Java разработчика";
//Используем метод replaceAll()
String st2 = st1.replaceAll("\\s", "");
System.out.println(st2);
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
Чтобы проверить, является ли число или строка палиндромом или нет, вы можете использовать любую переворачивающую строки программу, из описанных выше,.
Что вам нужно сделать, так это добавить один оператор if-else. Если исходная строка равна перевернутой строке, то число является палиндромом, в противном случае - нет.
import java.util.Scanner;
public class EighthTask{
public static void main (String[] args) {
String inputString, reversedString = "";
Scanner scannerQ = new Scanner(System.in);
int stringLength;
System.out.println("Введите число или строку");
inputString = scannerQ.nextLine();
stringLength = inputString.length();
for (int x = stringLength -1; x>=0; x--) {
reversedString = reversedString + inputString.charAt(x);
}
System.out.println("перевернутое значение: " + reversedString);
if(inputString.equals(reversedString))
System.out.println("Введенное значение является палиндромом");
else
System.out.println("Введенное значение не является палиндромом");
}
}
На экране получим:
Для строки-
Введите число или строку
dfggg
перевернутое значение: gggfd
Введенное значение не является палиндромом
Для числа-
Введите число или строку
777
перевернутое значение: 777
Введенное значение является палиндромом
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
class Test{
private int id;
private Integer id2;
public Test(int id, Integer id2) {
System.out.println("Создаем екзепляр Test");
this.id = id;
this.id2 = id2;
}
public Integer doIt(){
return id + id2;
}
}
class Test1{
private Test test;
private static int i;
public Test1() {
System.out.println("Создаем екзепляр Test1");
this.test = new Test(i, 10);
}
public Test getTest() {
return test;
}
}
class Main {
public static void main(String[] args) {
Test1 test1 = new Test1();
System.out.println(test1.getTest().doIt());
// Test test = new Test(null, 1);
// test.doIt();
}
}
Пишите ваши варианты ответов в комментариях.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Для чего нужна Double Brace инициализация в Java?
Double Brace инициализация используется в Java для наполнения коллекций(set, list, map, queue) одновременно с их объявлением. В случае если вам необходимо создать unmodifiable коллекцию, без Double Brace инициализации нам будет необходимо создать список, положить туда необходимое кол-во элементов и создать из этого списка unmodifiableList используя Collections класс. Используя Double Brace инициализацию мы имеем возможность "положить" в unmodifiableList все необходимые элементы сразу при объявлении.
@javatg
Double Brace инициализация используется в Java для наполнения коллекций(set, list, map, queue) одновременно с их объявлением. В случае если вам необходимо создать unmodifiable коллекцию, без Double Brace инициализации нам будет необходимо создать список, положить туда необходимое кол-во элементов и создать из этого списка unmodifiableList используя Collections класс. Используя Double Brace инициализацию мы имеем возможность "положить" в unmodifiableList все необходимые элементы сразу при объявлении.
@javatg
Здесь мы для начала вставили три элемента в переменную типа HashMap с именем keyValue, используя функцию put().
Размер переменной keyValue можно получить с помощью метода size(). После этого мы использовали цикл While для обхода keyValue, которая содержит по одной паре ключ-значение для каждого элемента. Ключи и значения могут быть получены с помощью методов getKey() и getValue().
Аналогично, мы используем расширенный цикл for, на элементах «qurentMe2» в HashMap.
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class SixthTask{
public static void main(String[] args) {
HashMap<Integer,String> keyValue = new HashMap<Integer,String>();
keyValue.put(1, "Hello");
keyValue.put(2, "World");
keyValue.put(3, "Have a nice day!");
System.out.println(keyValue.size());
System.out.println("Цикл While:");
Iterator iter = keyValue.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry qurentMe = (Map.Entry) iter.next();
System.out.println("Ключ это " + qurentMe.getKey() + " Значение это " + qurentMe.getValue());
}
System.out.println("Цикл For:");
for(Map.Entry qurentMe2: keyValue.entrySet()) {
System.out.println("Ключ это: " + qurentMe2.getKey() + " Значение это: " + qurentMe2.getValue());
}
}
}
На экране получим:
3
Цикл While:
Ключ это 1 Значение это Hello
Ключ это 2 Значение это World
Ключ это 3 Значение это Have a nice day!
Цикл For:
Ключ это: 1 Значение это: Hello
Ключ это: 2 Значение это: World
Ключ это: 3 Значение это: Have a nice day!
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
В следующем примере кода показан один из способов написания интерфейса с методом default и статическим методом:
public interface Interface1 {
// regular abstract method
void method1(String str);
default void log(String str) {
System.out.println("I1 logging::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Допустим нужно удалить n элементов с позиции m в списке. Вместо выполнения удаления одного элемента n раз (каждый раз смещая на 1 позицию элементы, стоящие «правее» в списке), нужно выполнить смещение всех элементов, стоящих «правее» n + m позиции на n элементов «левее» к началу списка. Таким образом, вместо выполнения n итераций перемещения элементов списка, все выполняется за 1 проход. Но если говорить об общей эффективности - то самый быстрый способ будет с использованием System.arraycopy(), и получить к нему доступ можно через метод - subList(int fromIndex, int toIndex)
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
ThreadPoolExecutor — описать механизм работы, св-ва, частности (fixed threadpool, scheduled, single thread executor)
ThreadPoolExecutor — средство контроля исполнения параллельных задач, задействует один из свободных тредов в общем пуле, или ставит задание в очередь, если таковых нет, или достигнуты определенные условия (ниже)
Основными св-вами ThreadPoolExecutor являются corePoolSize и maxPoolSize. Если текущее количество тредов в пуле < corePoolSize — новый тред будет создаваться в независимости от того, есть ли в пуле незанятые треды. В промежутке между corePoolSize и maxPoolSize тред будет создаваться в том случае, если заполнена очередь задач, и удаляться спустя keepAliveTime. Если кол-во тредов стало >= maxPoolSize — новые треды не создаются, а задачи ставятся в очередь.
Есть возможность регулировать поведение очереди:
• Direct handoffs: немедленная передача задачи тредпулу. Нет понятия очереди задачи. Если свободных тредов нет — кидается exception. Применимо при неограниченных maxPoolSize, но нужно понимать проблему при быстрых записях и медленных чтениях, что может спровоцировать непомерное потребление ресурсов
• Unbounded queues: очередь без ограничений. Задачи будут добавляться в нее при превышении corePoolSize, при этом maxPoolSize будет игнорироваться. Unbounded queues имеют проблемы потребления ресурсов при больших нагрузках, но сглаживают рост тредов при пиках.
• Bounded queues: очередь с ограничениями. Задачи будут добавляться в очередь до достижения некоего capacity. Для достижения наилучшей производительности нужно понимать размеры corePoolSize и самой очереди и чем можно пожертвовать — перфомансом (малый corePoolSize и большая очередь), или же памятью (ограниченная очередь, большой corePoolSize)
Частности ThreadPoolExecutor:
• ScheduleThreadPoolExecutor — применяется для периодичных по времени задач
• fixed thread pool — частность ScheduleThreadPoolExecutor'а с настроенным corePoolSize и unbounded queue
• single thread executor — тредпулл, c сorePoolSize = 1, гарантирующий последовательное выполнение задач из очереди
@javatg
ThreadPoolExecutor — средство контроля исполнения параллельных задач, задействует один из свободных тредов в общем пуле, или ставит задание в очередь, если таковых нет, или достигнуты определенные условия (ниже)
Основными св-вами ThreadPoolExecutor являются corePoolSize и maxPoolSize. Если текущее количество тредов в пуле < corePoolSize — новый тред будет создаваться в независимости от того, есть ли в пуле незанятые треды. В промежутке между corePoolSize и maxPoolSize тред будет создаваться в том случае, если заполнена очередь задач, и удаляться спустя keepAliveTime. Если кол-во тредов стало >= maxPoolSize — новые треды не создаются, а задачи ставятся в очередь.
Есть возможность регулировать поведение очереди:
• Direct handoffs: немедленная передача задачи тредпулу. Нет понятия очереди задачи. Если свободных тредов нет — кидается exception. Применимо при неограниченных maxPoolSize, но нужно понимать проблему при быстрых записях и медленных чтениях, что может спровоцировать непомерное потребление ресурсов
• Unbounded queues: очередь без ограничений. Задачи будут добавляться в нее при превышении corePoolSize, при этом maxPoolSize будет игнорироваться. Unbounded queues имеют проблемы потребления ресурсов при больших нагрузках, но сглаживают рост тредов при пиках.
• Bounded queues: очередь с ограничениями. Задачи будут добавляться в очередь до достижения некоего capacity. Для достижения наилучшей производительности нужно понимать размеры corePoolSize и самой очереди и чем можно пожертвовать — перфомансом (малый corePoolSize и большая очередь), или же памятью (ограниченная очередь, большой corePoolSize)
Частности ThreadPoolExecutor:
• ScheduleThreadPoolExecutor — применяется для периодичных по времени задач
• fixed thread pool — частность ScheduleThreadPoolExecutor'а с настроенным corePoolSize и unbounded queue
• single thread executor — тредпулл, c сorePoolSize = 1, гарантирующий последовательное выполнение задач из очереди
@javatg
SonarQube — платформа для проверки кода на качество по правилам, основанным на соглашениях и стандартах
Инструмент поддерживает 29 языков, в числе которых как ожидаемые Python, Java и C++, так и менее очевидные Cobol и Visual Basic
На первом месте в SonarQube находится измерение качества в соответствии с концепцией технического долга. Он, в свою очередь, вычисляется в долларах и человеко-днях, а также по типам показателей, в процентах
Стоимость: #бесплатно (но есть платные тарифы)
@javatg
Инструмент поддерживает 29 языков, в числе которых как ожидаемые Python, Java и C++, так и менее очевидные Cobol и Visual Basic
На первом месте в SonarQube находится измерение качества в соответствии с концепцией технического долга. Он, в свою очередь, вычисляется в долларах и человеко-днях, а также по типам показателей, в процентах
Стоимость: #бесплатно (но есть платные тарифы)
@javatg
Jivo Mobile SDK позволяет встроить чат в нативные мобильные приложения Android и принимать обращения клиентов. Интеграция занимает несколько минут, так как интерфейс чата с лентой сообщений уже реализован – вам понадобится только добавить несколько строк кода в ваш проект.
- Возможности актуальной версии
- Переписка клиента с оператором
- Отправка файлов в обе стороны
- История переписки клиента с оператором
- Статусы отправки и прочитанности сообщений в чате
- Базовые настройки UI
- Индикатор новых сообщений внутри приложения интегратора
- Push-уведомления
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
☕🛣️ Дорожная карта Java-разработчика в 2023 году: путь с нуля до первой работы
В данной статье мы расскажем, в каком порядке изучать Java, чтобы начать свой путь в разработке и стать востребованным специалистом в 2023 году.
Логическое и алгоритмическое мышление
Один из ключевых навыков для каждого разработчика – логическое и алгоритмическое мышление, которое необходимо развивать на каждом этапе карьеры. Большую часть времени разработчик ищет решения задач или применяет существующие алгоритмы, поэтому очень важно развивать логику и понимание алгоритмов.
➡️ Читать дальше
@javatg
В данной статье мы расскажем, в каком порядке изучать Java, чтобы начать свой путь в разработке и стать востребованным специалистом в 2023 году.
Логическое и алгоритмическое мышление
Один из ключевых навыков для каждого разработчика – логическое и алгоритмическое мышление, которое необходимо развивать на каждом этапе карьеры. Большую часть времени разработчик ищет решения задач или применяет существующие алгоритмы, поэтому очень важно развивать логику и понимание алгоритмов.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Java в вопросах и ответах: чего ожидать
Собеседование является одним из самых важных действий при трудоустройстве. И не обязательно в качестве программиста на Java/JS. Во время беседы потенциальный работодатель смотрит на соискателя, разговаривает с ним, пытаясь понять, насколько человек подходит для сотрудничества.
В коддинге на Java важно понимать – программера ждут вопросы, ответы на которые определят, насколько грамотен потенциальный работник. Человек, который планирует заниматься разработкой, должен хорошо разбираться в теории. И интервью здесь поможет оценить ситуацию.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
В этой программе мы добавили три элемента в ArrayList и вывели его размер.
Затем мы используем цикл While с итератором. Всякий раз, когда итератор получает следующий элемент, он будет отображать этот элемент, пока мы не достигнем конца списка. В нашем случае это будет повторяться три раза.
Аналогично, мы сделали для улучшенного цикла for, где мы создали объект o для ArrayList с именем testList. Затем вывели на экран значение объекта.
После этого мы создали цикла for, где итератор i установлен сначала на индекс 0, а затем увеличивается на 1 при каждой итерации, пока не будет достигнут предел ArrayList. Наконец, мы выводим на экран каждый элемент, используя метод get(index) для каждой итерации цикла for.
import java.util.*;
public class arrayList {
public static void main(String[] args) {
ArrayList testList = new ArrayList();
testList.add("50");
testList.add("60");
testList.add("70");
System.out.println(testList.size());
System.out.println("Цикл While:");
Iterator iter = testList.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
System.out.println("Улучшенный цикл For:");
for(Object o : testList) {
System.out.println(o);
}
System.out.println("Цикл For:");
for(int i=0; i< testList.size(); i++) {
System.out.println(testList.get(i));
}
}
}
На экране получим:
3
Цикл While:
50
60
70
Улучшенный цикл For:
50
60
70
Цикл For:
50
60
70
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
Эти типы программ обычно используются в рамках Selenium framework. Мы добавили подробные комментарии для каждого шага, чтобы сделать программу более понятной.
Логика начинается с того момента, как мы загрузили лист, на котором хранятся данные. Мы пытаемся импортировать электронную почту и пароль. Для этого мы извлекаем ячейку с помощью методов getRow() и getCell(). Допустим, у нас есть электронная почта и пароли в 1-й и 2-й ячейке.
Далее мы устанавливаем тип ячейки - строковой. После этого мы выполняем обычную операцию локатора веб-элемента (By.id), куда мы передали уникальные значения локатора, такие как «email» и «пароль», которые будут идентифицировать эти элементы.
Наконец, мы отправляем ключи, используя element.sendKeys, где cell.getStringCellValue() - это ключ. Эта операция вернет вам значение, сохраненное в ячейках № 1 и 2 соответственно.
@Test
public void ReadData() throws IOException
{
// импортируйте лист Excel из директории web диска c.
//QurentSourceFile – это имя нужного файла excel
File sourceFile=new File("C:\\web\\QurentSourceFile.xls");
// На этом шаге мы загружаем файл. Мы используем FileInputStream для чтения из
// файла excel. В случае если вы хотите проводить запись в файл -
// вам следует использовать FileOutputStream. Путь к файлу передается в качестве
// аргумента FileInputStream
FileInputStream fileInput = new FileInputStream(sourceFile);
// На этом шаге мы загружаем рабочую книгу excel с помощью HSSFWorkbook,
// в который мы передаем fileInput в качестве аргумента
HSSFWorkbook book = new HSSFWorkbook(fileInput);
// На этом шаге мы загружаем конкретный лист excel, на котором хранятся данные.
qurentSheet= book.getSheetAt(0);
for(int i=1; i<= qurentSheet.getLastRowNum(); i++)
{
// Import data for Email.
qurentCell = qurentSheet.getRow(i).getCell(1);
qurentCell.setCellType(Cell.CELL_TYPE_STRING);
driver.findElement(By.id("email")).sendKeys(qurenrCell.getStringCellValue());
// Импортируем данные из ячеек с паролями.
qurentCell = qurentSheet.getRow(i).getCell(2);
qurentCell.setCellType(Cell.CELL_TYPE_STRING);
driver.findElement(By.id("password")).sendKeys(qurenrCell.getStringCellValue());
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Casting
, или приведение типов — это процесс преобразования одного типа данных в другой тип данных: вручную (неявное приведение) или автоматически (явное приведение типов).Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 16 - 7Автоматическое преобразование выполняет компилятор, а ручное — разработчик.
Приведение типов для примитивов и классов несколько отличается, поэтому и рассмотрим их по отдельности.
Примитивные типы
Пример автоматического приведения примитивных типов:
int value = 17;
double convertedValue = value;
Как видите, никаких дополнительных манипуляций помимо знака = тут не нужно.
Пример ручного приведения примитивных типов:
double value = 17.89;
int convertedValue = (int)value;
В этом случае мы можем наблюдать ручное приведение, которое реализуется с помощью (int), при этом часть за запятой будет отброшена, и convertedValue будет иметь значение - 17.
Подробнее о приведении примитивных типов читайте в этой статье.
Ну а теперь давайте перейдем к объектам.
Ссылочные типы
Для ссылочных типов автоматическое приведение возможно для классов наследников к классам родителям. Это так же называется полиморфизмом.
Предположим, у нас есть класс Lion, который наследуется от класса Cat. В этом случае автоматическое преобразование будет выглядеть так:
Cat cat = new Lion();
А вот с явным приведением всенесколько сложнее, ведь нет функционала обрезания лишнего, как у примитивов.
И сделав просто явно преобразование вида:
Lion lion= (Lion)new Cat();
Вы и получите ошибку:
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 16 - 8В самом деле, вы можете классу наследнику Lion добавить методы, которых не было изначально в классе Cat, и потом пытаться их вызвать, ведь типа объекта у вас станет Lion. Ну а в этом логики никакой нет.
Поэтому, сужение типа возможно лишь когда изначальный объект типа Lion, но был позже приведен к классу родителя:
Lion lion = new Lion();
Cat cat = lion;
Lion newLion = (Lion)cat;
Также, для большей надежности, сужающее приведение для объектов рекомендуется с использованием конструкции instanceOf:
if (cat instanceof Lion) {
newLion = (Lion)new Cat();
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
10 бесплатных курсов по программированию на Java для начинающих в 2023 году
Не тратя больше ваше времени, вот мой список лучших онлайн-курсов для БЕСПЛАТНОГО изучения Java. Я попытался включить различные виды курсов, такие как бесплатные курсы для изучения базовой Java, а также курсы о многопоточности, объектно-ориентированного программирования и т. д.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Mock-Собеседование на позицию Java Junior Developer. Часть 1.
Mock-Собеседование на позицию Java Junior Developer. Часть 1.
Всем привет, друзья! Выпускаю для вас первую часть собеседования с сильным кандидатом на позицию juinor java разработчика - Феликсом. Сегодня постараемся найти слабые кандидата и проверим его знания…
Всем привет, друзья! Выпускаю для вас первую часть собеседования с сильным кандидатом на позицию juinor java разработчика - Феликсом. Сегодня постараемся найти слабые кандидата и проверим его знания…