Jav Aoi

👉🏻👉🏻👉🏻 ALL INFORMATION CLICK HERE 👈🏻👈🏻👈🏻
Jav Aoi
Все потоки
Разработка
Администрирование
Дизайн
Менеджмент
Маркетинг
Научпоп
24,4k
121
17,5k
22
28,1k
154
2k
2
4,1k
13
37,2k
164
+12
8,4k
47
11
+11
20,6k
81
43
+12
213k
328
14
Аналог Arrays.asList() для Set не нужен, всегда можно передать результат Arrays.asList в конструктор HashSet. Чаще всего такая инициализация востребована в статических константах, а значит лишняя аллокация не имеет значения.
Ну то есть вы предлагаете писать так?
Set set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c")));
Очень удобно, ничего не скажешь.
так что на killer-фичу, заставляющую обновляться даже близко не подходит
Где я утверждал, что это киллер-фича? Вы взяли из списка наименее востребованные функции, и сделали вывод, что мигрировать не нужно. А остальные функции проигнорировали. Что скажете по поводу ProcessHandle, takeWhile, Cleaner? Почему вы делаете суждения исходя из востребованности каждой отдельной функции, а не их в совокупности? А почему вы проигнорировали тот факт, что это лишь первая часть? Будут ещё статьи и будет ещё много API.
Что касается коллекций — есть прекрасные Eclipse Collections — www.eclipse.org/collections . Писать получается гораздо выразительнее и короче. Иногда — сильно выгоднее по памяти. Есть даже отдельный субпроект для изучения — github.com/eclipse/eclipse-collections-kata
Stream записей является почти бесконечным, поэтому filter() использовать не получится а почему?
Неэффективно будет. takeWhile остановится сразу, а filter будет идти до самого конца.
Любопытно будет посмотреть, как вы самостоятельно будете писать Process.pid или Cleaner :)
Эта проблема должна красиво решаться через pattern matching в switch/case, осталось дождаться.
Эта проблема вполне красиво решается через Vavr. И его Option, с несколькими дополнительными плюшками. Ну т.е. это — как раз тот случай, когда такое можно написать самому, и уже написали.
Видел уже несколько раз баги:
В погоне за модой фукнкионального стиля люди начинают использовать
requireNonNullElse() или orElse()
и код который был в ветви else, которая раньше не выполнялась, теперь выполняется всегда, причем до основного if (который теперь стал filter или anyMatch).
Optional.ofNullable() тоже зло.
Люди пихают его везде, просто по привычке чтобы не парится с нуллами.
В итоге баги доходят до UI и живут пока юзеры не пожалуются что у них тут что-то пустое место вместо нужных им цифр.
Не правильно готовят Optional : вместо orElse() надо использовать orElseGet() , чтоб ветка else выполнялась только по необходимости.
А какие есть причины не переходить на kotlin?
НЛО прилетело и опубликовало эту надпись здесь
Именно из-за уменьшения количества писанины
В Котлине не все методы из списка есть
А вам шашечки или ехать? Без этих методов раньше не могли что-то сделать?
// Java 9+
IntStream
.iterate(1, i -> i < 100, i -> i * 2)
.forEach(System.out::println);
Это вообще, садизм. Как надо было заоптимизировать цикл for, что бы нативный инкремент регистра процессора стал медленнее stream.
В вашем примере вообще не видно, медленно или быстро. И вообще ниоткуда это не видно. Можно пояснить, о чем тут речь?
Вы читать умеете статью? И так, имеется базовый цикл
/ Java 8
for (int i = 1; i < 100; i *= 2) {
System.out.println(i);
}
Переменная i, это не Java Object, а вполне себе, достаточная переменная, внутри стека. Посмотрим на конструкцию
.iterate(1, i -> i < 100, i -> i * 2)
Тут, как минимум, 2 замыкания. Как вы думаете, что быстрее выполнится, просто операция или замыкание, выполняющее эту операцию?
Если уж приводить пример, надо показывать действительно то, что не будет выглядеть на столько бессмысленным.
>Вы читать умеете статью?
Статья-то тут при чем? Перечитайте свою изначальную фразу:
Как надо было заоптимизировать цикл for, что бы нативный инкремент регистра процессора стал медленнее stream.
Что тут медленнее чего, кого оптимизировали — вообще непонятно. Не в статье — а у вас. Сейчас со второго раза другими словами — уже норм, но сначала было как-то мрачно.
Если уж приводить пример, надо показывать действительно то, что не будет выглядеть на столько бессмысленным.
Ну ёлы-палы, добавьте пару операций к стриму, и он сразу же станет смысленным. Ну, так, например:
System.out.println(IntStream
.iterate(1, i -> i < 100, i -> i * 2)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "))); // 1, 2, 4, 8, 16, 32, 64
А с циклом for то же самое будет уже сильно сложнее.
Победа производительности системы достаётся одной строке
System.out.println("1, 2, 4, 8, 16, 32, 64");
Я всё равно буду стоять на своём, что надо показывать примеры эффективного использования разных конструкций. На практике, бывает настолько не эффективное использование. Например, старый добрый интерфейс итератора. Итератор удаляет пустые строки.
List list; // размер списка, порядка 20-30 записей
for(Iterator it; it.hasHext(); ) {
String val = it.next();
if (val == null || val.isEmpty()) it.remove();
}
return list;
Превращается в поток, фильтр и преобразование в новый список. Красиво — да. Эффективно — нет. Если усложнять задачу, возможно, будет эффективней переход на потоки.
Возвращаясь к оператору for, методу iterate не всегда применим. Скажем, нам нужен бесконечный цикл и выход по некоторому условию. В замыкании нет break, для прерывания цикла и нет return для остановки потока. Или всё это есть?
А разве в вашем примере для Java 8 неявно не создаётся Иммутабельный список уже даже без обертывания в unmodifiableList ?
ListArrays.asList("bmp", "jpg", "png", "gif");
Попытка добавить в такой список что-либо приведет к java.lang.UnsupportedOperationException
Долго работал на С# и тут позвали джаву писать, ну и раз зп не меньше то я пошёл, учусь быстро и хоть какой-то опыт есть. И спустя неделю работы я понял какая джава недоделанная, есть конечно плюсы, но по сравнению с.нет библиотеки остановились на стадии бета где не подготовленный пользователь отойдя хоть немного от семплов сразу получает кучу проблем. Может есть и лучше решения, но я вроде как пришёл в проект к опытным, а оказалось что они умеют сложно писать, а не правильно. Версия у нас старенькая, но то чту тут предложено трудно назвать апгрейдом. В с# почти каждая версия даёт полноценный новый инструмент, а тут слабенько
Да, согласен, это слабенько. Потому что ничего кроме этих 10 методов в новых версиях Java не появилось.
--sarcasm mode off--
Откройте вы уже список JEP'ов в начале статьи и посмотрите, что добавилось.
И Вы, конечно же, сейчас сможете привести примеры, подтверждающие Ваши слова!?
2,2k
17
10,6k
22
3,3k
20
5,2k
85
+34
28,1k
94
154
+84
28,3k
96
296
+52
37,2k
169
164
+10
24,4k
2
121
Публикации
Новости
Хабы
Компании
Пользователи
Песочница
Устройство сайта
Для авторов
Для компаний
Документы
Соглашение
Конфиденциальность
Реклама
Тарифы
Контент
Семинары
Мегапроекты
Мерч
На сегодняшний день Java 8 является самой популярной версией Java и ещё довольно долго будет ей оставаться. Однако с тех пор уже выпущено пять новых версий Java (9, 10, 11, 12, 13), и совсем скоро выйдет ещё одна, Java 14. В этих новых версиях появилось гигантское количество новых возможностей. Например, если считать в JEP'ах, то в сумме их было реализовано 141:
Однако в этом цикле статей не будет никакого сухого перечисления JEP'ов. Вместо этого я хочу просто рассказать об интересных API, которые появились в новых версиях. Каждая статья будет содержать по 10 API. В выборе и порядке этих API не будет какой-то определённой логики и закономерности. Это будет просто 10 случайных API, не ТОП 10 и без сортировки от наиболее важного API к наименее важному. Давайте начнём.
Начнём мы наш список с двух очень простеньких, но очень полезных методов в классе java.util.Objects : requireNonNullElse() и requireNonNullElseGet() . Эти методы позволяют вернуть передаваемый объект, если он не null , а если он null , то вернуть объект по умолчанию. Например:
requireNonNullElseGet() – это не что иное, как просто ленивая версия requireNonNullElse() . Она может пригодиться, если вычисление аргумента по умолчанию является затратным:
Да, конечно же в обоих случаях можно было бы легко обойтись и без этих функций, например, использовать обычный тернарный оператор или Optional , но всё же использование специальной функции делает код немножко короче и чище. А если использовать статический импорт и писать просто requireNonNullElse() вместо Objects.requireNonNullElse() , то код можно сократить ещё сильнее.
Если предыдущие два метода – это просто косметика, то статические методы-фабрики коллекций позволяют действительно сильно сократить код и даже улучшить его безопасность. Речь о следующих методах, появившихся в Java 9:
К этому же списку можно добавить сопутствующий метод Map.entry(K k, V v) , создающий Entry из ключа и значения, а также методы копирования коллекций, которые появились в Java 10:
Статические методы-фабрики позволяют создать неизменяемую коллекцию и инициализировать её в одно действие:
Если не пользоваться сторонними библиотеками, то аналогичный код на Java 8 выглядит гораздо более громоздким:
А в случае с Set или Map всё ещё печальнее, потому что аналогов Arrays.asList() для Set и Map не существует.
Такая громоздкость провоцирует многих людей, пишуших на Java 8, вообще отказываться от неизменяемых коллекций и всегда использовать обычные ArrayList , HashSet и HashMap , причём даже там, где по смыслу нужны неизменяемые коллекции. В результате это ломает концепцию immutable-by-default и снижает безопасность кода.
Если же наконец обновиться с Java 8, то работать с неизменяемыми коллекциями становится намного проще и приятнее благодаря методам-фабрикам.
Java всегда была известна своей неспешностью вводить готовые методы для частых операций. Например, для одной из самых востребованных операций в программировании, чтения файла, очень долго не было готового метода. Лишь спустя 15 лет после выхода Java 1.0 появилось NIO, где был введён метод Files.readAllBytes() для чтения файла в массив байтов.
Но этого всё ещё не хватало, потому что людям часто приходится работать с текстовыми файлами и для этого нужно читать из файла строки, а не байты. Поэтому в Java 8 добавили метод Files.readAllLines() , возвращающий List .
Однако и этого было недостаточно, так как люди спрашивали, как просто прочитать весь файл в виде одной строки. В итоге, для полноты картины в Java 11 добавили долгожданный метод Files.readString() , тем самым окончательно закрыв этот вопрос. Удивительно, что если аналогичный метод присутствовал во многих других языках с самого начала, то Java для этого потребовалось больше 20 лет.
Вместе с readString() конечно же ввели и симметричный метод writeString() . Также у этих методов есть перегрузки, позволяющие указать Charset . В совокупности всё это делает работу с текстовыми файлами чрезвычайно удобной. Пример:
Когда Optional появился в Java 8, для него не сделали удобного способа выполнить два разных действия в зависимости от того, есть ли в нём значение или нет. В итоге людям приходится прибегать к обычной цепочке isPresent() и get() :
Либо можно извернуться ещё таким образом:
Оба варианта не идеальны. Но, начиная с Java 9, такое можно сделать элегантно с помощью метода Optional.ifPresentOrElse() :
Ещё одним новым интересным методом в Java 9 стал Optional.stream() , который возвращает Stream из одного элемента, если значение присутствует, и пустой Stream , если отсутствует. Такой метод может быть очень полезен в цепочках с flatMap() . Например, в этом примере очень просто получить список всех телефонных номеров компании:
В Java 8 пришлось бы писать что-нибудь вроде:
Это выглядит громоздко и не очень читабельно.
Если без предыдущих API обойтись худо-бедно ещё можно, то вот замену метода Process.pid() в Java 8 найти будет довольно проблематично, особенно кроссплатформенную. Этот метод возвращает нативный ID процесса:
Также с помощью метода Process.info() можно узнать дополнительную полезную информацию о процессе. Он возвращает объект типа ProcessHandle.Info . Давайте посмотрим, что он вернёт нам для процесса выше:
Что делать, если процесс был запущен не из текущего Java-процесса? Для этого на помощь приходит ProcessHandle . Например, давайте достанем всю ту же самую информацию для текущего процесса с помощью метода ProcessHandle.current() :
Чтобы получить ProcessHandle для любого процесса по его PID, можно использовать метод ProcessHandle.of() (он вернёт Optional.empty , если процесса не существует).
Также в ProcessHandle есть много других интересных методов, например, ProcessHandle.allProcesses() .
Целая гора полезных методов для строк появилась в Java 11.
Метод String.isBlank() позволяет узнать, является ли строка состоящей исключительно из whitespace:
Методы String.stripLeading() , String.stripTrailing() и String.strip() удаляют символы whitespace в начале строки, в конце строки или с обоих концов:
Заметьте, что String.strip() не то же самое, что String.trim() : второй удаляет только символы, чей код меньше или равен U+0020, а первый удаляет также пробелы из Юникода:
Метод String.repeat() конкатенирует строку саму с собой n раз:
Наконец, метод String.lines() разбивает строку на линии. До свидания String.split() , с которым люди постоянно путают, какой аргумент для него использовать, то ли "\n" , то ли "\r" то ли "\n\r" (на самом деле, лучше всего использовать регулярное выражение "\R" , которое покрывает все комбинации). Кроме того, String.lines() зачастую может быть более эффективен, поскольку он возвращает линии лениво.
Давайте разбавим наш рассказ чем-нибудь свежим, что появилось совсем недавно. Встречайте: метод String.indent() , который увеличивает (или уменьшает) отступ каждой линии в данной строке на указанную величину. Например:
Заметьте, что для последней линии String.indent() сам вставил перевод строки, поэтому нам не пришлось добавлять '\n' после body.indent(4) .
Конечно, наибольшый интерес такой метод будет представлять в сочетании с блоками текста , когда они станут стабильными, но ничто не мешает использовать его уже прямо сейчас без всяких блоков текста.
Stream.takeWhile() похож на Stream.limit() , но ограничивает Stream не по количеству, а по предикату. Такая необходимость в программировании возникает очень часто. Например, если нам надо получить все записи в дневнике за текущий год:
Stream записей является почти бесконечным, поэтому filter() использовать не получится. Тогда на помощь приходит takeWhile() :
А если мы хотим получить записи за 2019 год, то можно использовать dropWhile() :
В Java 8 Stream.iterate() мог генерировать только бесконечный Stream . Но в Java 9 у этого метода появилась перегрузка , которая принимает предикат. Благодаря этому многие циклы for теперь можно заменить на Stream :
Обе этих версии печатают все степени двойки, которые не превышают 100 :
Кстати, последний код можно было бы переписать с использованием takeWhile() :
Однако вариант с трёхаргументным iterate() всё-таки чище (и IntelliJ IDEA предлагает его исправить обратно).
Наконец, Stream.ofNullable() возвращает Stream с одним элементом, если он не null , и пустой Stream , если он null . Этот метод отлично подойдёт в примере выше с телефонами компании, если getPhoneNumber() будет возвращать nullable String вместо Optional :
Этот метод не вносит ничего принципиально нового и носит скорее косметический, нежели фундаментальный характер. И всё же возможность немного подсократить код всегда очень приятна. С помощью Predicate.not() лямбды, в которых есть отрицание, можно заменить на ссылки на методы:
Да, экономия не такая уж и огромная, а если использовать s -> !s.isEmpty() , то количество символов, наоборот, становится больше. Но даже в этом случае я всё равно предпочту второй вариант, так как он более декларативен и в нём не используется переменная, а значит не захламляется пространство имён.
Сегодняшний рассказ я хочу завершить новым интересным API, появившимся в Java 9 и служащим для очистки ресурсов перед их утилизацией сборщиком мусора. Cleaner является безопасной заменой метода Object.finalize() , который сам стал deprecated в Java 9.
С помощью Cleaner можно зарегистрировать очистку ресурса, которая произойдёт, если её забыли сделать явно (например, забыли вызвать метод close() или не использовали try-with-resources ). Вот пример абстрактного ресурса, для которого в конструкторе регистрируется очищающее действие:
По-хорошему, такой ресурс пользователи должны создавать в блоке try :
Однако могут найтись пользователи, которые забудут это делать и будут писать просто var resource = new Resource() . В таких случаях очистка выполнится не сразу, а позовётся позже в одном из следующих циклов сборки мусора. Это всё же лучше, чем ничего.
Если вы хотите изучить Cleaner получше и узнать, почему никогда не стоит использовать finalize() , то рекомендую вам послушать мой доклад на эту тему.
Java не стоит на месте и постепенно развивается. Пока вы сидите на Java 8, с каждым релизом появляется всё больше и больше новых интересных API. Сегодня мы рассмотрели 10 таких API. И вы сможете использовать их все, если наконец решитесь мигрировать с Java 8.
В следующий раз мы рассмотрим ещё 10 новых API.
Присылаем лучшие статьи раз в месяц
Аналог Arrays.asList() для Set не нужен, всегда можно передать результат Arrays.asList в конструктор HashSet. Чаще всего такая инициализация востребована в статических константах, а значит лишняя аллокация не имеет значения.
Что касается Map-а, в java8 использую комбинацию Stream.of с SimpleImmutableEntry (вот она замена Map.entry) и последующий collect в Map.
Да, вариант более многословный, но стандартные, уменьшающие громоздкость объявления констант заменяются нестандартными методами, так что на killer-фичу, заставляющую обновляться даже близко не подходит.
Кучка функций для замены commons-lang и подобных пакетов — это круто, но пока они появляются точечно, от сторонних пакетов отказаться не получится, а это заметно осложняет переход (зачем учить новое апи, если всё равно требуется использовать стороннюю библиотеку, в которой уже есть куча функций, которыми уже привык пользоваться). Конечно, появление этих функций в стандартной джаве — это круто, но почему это происходит так избирательно?
Что касается Predicate.not, в java8 есть Predicate.negate(), правда, он требует использования вспомогательной функции, либо явного каста, иначе компилятор не понимает, что это предикат (это, вроде, должны были починить в одной из более поздних версий). Да, Predicate.not — удобная штука, но на killer-фичу не тянет даже близко.
Что касается ProcessHandle и Cleaner, то первый нужен для специфических целей и его появление обязано расширению границ применения java вообще, а к последнему я отношусь как к обычной смене одного апи на другое (лично мне пришлось писать финализатор лишь единожды). Что касается гарантий закрытия у Closable, появление достаточно умных ide, которые теперь ругаются на отсутствие вызова close у Closable-объекта, делает данную защиту от забытого close менее острой чем раньше.
В моей практике они были нужные почти никогда. Точнее ProcessHandle — вообще ни разу, takeWhile — потенциально пару раз мог пригодиться, а Cleaner — чистейший code smells.
"Я это не использую, значит оно не нужно"
Оно не нужно в вебе, оно мало кому нужно в десктопных приложениях. Я не говорю, что реализация этого API плохо, я отвечаю на ваш домысел, что это "востребованные функции". Но дело в том, что они востребованы в узком списке специфических потребностей, а большинству — не нужны. Т.е. они из категории "есть и хорошо", а не из категории "дайте срочно мне!". Вот стримы и nio отвечали потребностям более широкой аудитории, поэтому на java 7/8 переход был более массовый, чем переход на более современные. Ну вот поставил я себе 11-ую JDK и не пользуюсь её фичами (кошмар какой?!)...
А ещё есть прекрасные Guava. Все эти List.of(), Set.of() и прочее всегда были там, в более явном виде ImmutableList.of(), ImmutableSet.of() etc.
На Java 9+ пока переходить не хочу, т.к. не понимаю, как правильно использовать модули в веб-приложениях. Подожду, пока выйдет новый JEE, где это учтут и когда выйдет и стабилизируется новый Tomcat.
Новые API по сути ерундовые и легко пишутся самостоятельно. За список спасибо, это полезно знать. Я некоторые методы выношу в свои util классы. Если всё-таки мигрирую, просто заменю реализацию на JDK и сделаю рефакторинг inline method, в итоге с минимальными усилиями получится правильный код.
Ну такое не смогу, да, но зачем оно надо, не представляю.
Чего только не придумают, лишь бы не добавлять в язык elvis operator. Неужели никому из тех кто работал с этим JEP не показалось, что эта конструкция как минимум громоздкая и неуклюжая? Кто-нибудь в курсе, почему изменений непосредственно языка боятся как огня? Я ещё могу принять объяснение, которое приводили против литералов коллекций — такая конструкция гвоздями прибила бы язык к стандартной библиотеке, потому что нужно было бы специфицировать, какой тип коллекции должен возвращать литерал (хотя наличие autoboxing'а, Iterable и AutoClosable уменьшают вес этого аргумента). Но чем помешает прокачка тернарного оператора? Сочетание символов ?: и так является невалидным, введение его как языковой конструкции не сломает существующий код. Равно как оператор ?. для null-safe доступа к методам и свойствам. Да, Optional удобен в тех ситуациях, когда нужно явно обозначить, что значение может отсутствовать, но писать Optional.ofNullable() (кстати, почему Optional.of() бросает NPE если на входе null?) каждый раз, когда хочется просто получить вложенное свойство — неудобно.
Не поймите меня неправильно, я не хейтер, я сам пишу на Java и радуюсь улучшению API стандартной библиотеки. Но requireNonNullElse — это какой-то сюр.
Смело, очень смело. Ждем в релизе.
Но насколько я понял из листа, паттернматч применим только к определению типов, об общем назначении речь не идет.
Потому что Optional сделан как обертка над нуллабельным полем типа T , соответственно отличить пустой Optional от Optional.of(null) нет возможности. Наверное в теории можно было бы сделать так чтобы Optional.of(null) возвращал пустой Optional , но вероятно для дополнительной null-безопасности решили этого не делать.
Optional.ofNullable() это не мешает. Всё отличие между of() и ofNullable() заключается в простой проверке на null. Если Optional делали как средство борьбы с NPE, то почему более коротким (читай — дефолтным) сделали метод, который ожидает не-null аргумент? Неужели пытались производительность улучшить, убрав один if?
Единственная весомая причина не переходить на котел — прибитый гвоздями к легаси энтерпрайз. Все-таки соединение котел-джава не совсем стабильное и бесшовное, и использовать существующие джава-библиотеки может быть не так и просто.
В остальном же, любой, кто видел в жизни кроме джавы вообще хоть что-то, выберет котел без раздумий.
Только полноправные пользователи могут оставлять комментарии. Войдите , пожалуйста.
Java Platform SE 8
API , ради которых наконец-то стоит обновиться с Java ...
План изучения Java | 8. API -клиенты
Список Java API — Wikimedia Foundation
List of Java APIs - Wikipedia
2 декабря 2019
24590
просмотров
16
комментариев
Чтобы просмотреть все комментарии или
оставить свой,
перейдите в полную версию
wan-derer.ru
40
уровень, Москва
Писос какой-то... Зачем я в это ввязался?! сидел бы спокойно у себя в ларьке с шаурмой...
Антон Шеленков
36
уровень, Москва
Многое в точку, но по моему мнению не все. Стадию джуна я прошел, поэтому поделюсь мыслями о том, что бы я изменил в этом плане развития, чтоб максимально сократить время обучения до первой работы (и при этом не оставить сильных пробелов в знаниях):
0. О всех вещах, перечисленных на картинке надо иметь как минимум представление на уровне "что это такое и какую функцию выполняет"
1. Если уж идет речь о многопоточности, то знать ThreadPool, Executor, Callable, Locks - must have. Это то, с чем в реальности придется иметь дело.
2. Где теоретический минимум по сетям и протоколам? Надо знать модель OSI, HTTP (желательно еще понимать HTTPS), REST.
3. IntelliJ IDEA vs Eclipse - однозначно IntelliJ IDEA. Желательно освоить Ultimate Edition (можно ее купить или активировать по другому, если вы понимаете о чем я)
4. Maven vs Gradle - Maven легче и по ощущениям более распространен, чем Gradle. Имхо нет смысла начинать с Gradle
5. Алгоритмы и структуры - надо знать в основном структуры (стек, очередь, список, деревья) и сложность операций с ними. Всякие сортировки и более прошаренные структуры можно доучить потом.
6. NIO - все руки не доходят раскурить этот API:) Вряд ли понадобится в 99% случаев. Я б оставил на потом
7. Сервлеты - must have, JDBC стоит просмотреть мельком ради академического интереса, но вот учить API и как-то им грузиться точно лишнее - он слишком уж на низком уровне
8. Spring Data JPA поверх Hibernate. Изучение азов займет немного времени, но стоит того
9. MySQL - однозначно нафиг. Стоит начинать с PostgreSQL - он сложнее, но при этом намного более распространен, чем MySQL
10. NoSQL - лезть туда джуну далеко не обязательно. Больше выхлопа будет, если это время потратить на другие вещи
Да, а от Java Script плавно переходите к React и Redux. Можно любые соседние брать - тоже хорошо. Может так получиться, что отдельных UI-щиков нет и ты должен писать и бэкенд, и фронтенд. А иногда и в базу залезать :) Короче, все надо уметь, но специализацию выбрать - к чему более тяготеешь. Спасибо за статью, товарищи!
Александр
35
уровень, Краснодар
Хорошая статья, особенно инфографика.
TheVoda
35
уровень, Воронеж
Спасибо огромнейшее, супер статья. Сколько бы не учился, а куда не заглянешь - везде эльфийский, а вы тут как раз весь эльфийский алфавит выложили)
Egor
41
уровень, Санкт-Петербург
Господа Администраторы, было бы прикольно иметь возможность добавлять статьи в избранное, а потом просматривать/сортировать/удалять их в избранном) А то уже закладок в браузере пруд пруди)
©
2021
JavaRush
«Программистами не рождаются»
IDE или интегрированная среда разработки
Инструменты для автоматической сборки
Системы контроля версий и сервисы онлайн-хостинга
Free Sister Deepthroat
Real Amature Pussy Pics
Asian Swimsuit Sex
Stripping Girl Pics
Girl Upskirt Porn




















































