Статьи

Stackoverflow: 7 из лучших ответов Java, которые вы не видели

Какие самые интересные ответы вы можете найти в Stackoverflow?

Stackoverflow — золотая жила для разработчиков. Это помогает нам находить наиболее полезные ответы на конкретные проблемы, с которыми мы сталкиваемся, и мы всегда узнаем что-то новое из этого.

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

Java ответы для всех

Java является вторым по популярности тегом в Stackoverflow, с которым связано более миллиона вопросов. За последнюю неделю на сайт было загружено более 4600 вопросов, и, без сомнения, это самое большое и активное онлайн-сообщество разработчиков.

Эта информация неразрывно связана с результатами опроса разработчиков Stackoverflow за 2016 год , в котором 56 033 программиста спросили, какой язык они предпочитают. Ява заняла 3 место:

Наиболее популярная технология

Самые популярные технологии 2016 года. Источник: Stackoverflow

Мы уже знаем, что Java правит рынком труда , и можно с уверенностью предположить, что вы тоже посетили Stackoverflow один или два раза, чтобы найти ответ на вопрос. Однако, даже если вы просто просматриваете Stackoverflow без особого вопроса, может появиться множество интересных вещей. Давайте посмотрим на некоторые из этих драгоценных камней.

1. Прогнозирование отрасли

Один из самых популярных вопросов Java по Stackoverflow: « Почему быстрее обрабатывать отсортированный массив, чем несортированный массив? ». Чтобы ответить на это, вам нужно использовать предсказание ветвления. Это архитектура, которая направлена ​​на улучшение потока приложений путем угадывания того, каким образом пойдет конкретная ветвь, прежде чем будет выбран фактический путь. Образованное предположение, если хотите, только на самом деле это не предположение.

1
2
3
4
5
6
7
8
9
for (int i = 0; i < 100000; ++i)
        {
            // Primary loop
            for (int c = 0; c < arraySize; ++c)
            {
                if (data >= 128)
                    sum += data;
            }
        }

Ветвь здесь — это оператор if. В этом случае, если массив отсортирован, предсказание ветви будет работать. Если он не отсортирован, он не будет работать.

Мистик попытался объяснить это более простым способом, используя железную дорогу и поезд. Представьте, что вы управляете развязкой, и вам нужно решить, в какую сторону будет идти поезд, вы выберете левую или правую? Конечно, вы можете остановить поезд и спросить водителя, какой путь является правильным, но это делает весь процесс медленным, неуклюжим и раздражающим. Вам нужно сделать предположение. Как вы можете быть уверены, что ваша догадка верна? Взгляните на прошлые поездки текущего поезда и поймите, по какому пути он идет каждый раз.

Это прогноз отрасли: выявлять закономерности и следовать им.

К сожалению, в этом случае пользователь, задавший главный вопрос, стал жертвой сбоя прогнозирования ветвлений. Это произошло из-за того, что у ветви не было узнаваемого шаблона, поэтому попытки предсказать его действия довольно случайны.

2. Безопасность в Java

Другой популярный вопрос, который часто поднимают пользователи Java: « Почему char [] предпочтительнее, чем String для паролей в Java? ». Сам вопрос немного более конкретен: он спрашивает, почему в поле пароля Swing есть метод getPassword () (возвращает char []) вместо getText () (возвращает String).

Здесь нет ничего удивительного — это проблема безопасности. Строки являются неизменяемыми, то есть вы не можете изменять их после того, как они созданы. Это также означает, что вы не можете избавиться от данных, пока GC не постучит. В случае, если кто-то получит доступ к вашей памяти, ему может быть доступна строка с паролем.

Вот почему вы должны использовать массив символов. Вы сможете явно стереть данные, когда закончите с ними, или можете перезаписать их чем угодно. Чувствительные данные не будут присутствовать где-либо в системе, даже до запуска GC.

3. Исключения

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

Один из наиболее часто задаваемых вопросов — «Что такое исключение NullPointerException и как его исправить?». Мы не были шокированы, увидев, насколько популярным является это исключение, поскольку оно также оценивается как тип исключения номер 1 в производственных приложениях Java .

В Takipi у нас фактически есть возможность настраивать оповещения всякий раз, когда в системе вводится новое исключение NullPointerException (или любое другое исключение). Проверьте это .

4. Причуды и магия

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

Почему этот код с использованием случайных строк выводит «hello world»?

На вопрос поставлено следующее печатное утверждение, которое печатает «привет мир»:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
public static String randomString(int i)
{
    Random ran = new Random(i);
    StringBuilder sb = new StringBuilder();
    while (true)
    {
        int k = ran.nextInt(27);
        if (k == 0)
            break;
 
        sb.append((char)('`' + k));
    }
 
    return sb.toString();
}
 
System.out.println(randomString(-229985452) + " " + randomString(-147909649));

Ответ в том, что нет ложки. Это означает, что выбор случайного набора целых чисел не будет случайным. Вместо этого экземпляр будет следовать алгоритму генерации случайных чисел, который начинается с определенного параметра начального числа (в этом случае -229985452 или -147909649). Каждый раз, когда вы будете запрашивать случайный шаблон, это же семя будет генерировать один и тот же шаблон — который будет распечатывать привет мир.

Пользователь Eng.Fouad объяснил это прекрасно:

В новом Random (-229985452) .nextInt (27) первые 6 чисел, которые генерирует случайное число:
8, 5, 12, 12, 15, 0

И первые 6 чисел, которые генерирует новый Random (-147909649) .nextInt (27):
23, 15, 18, 12, 4, 0

Когда вы добавляете эти числа к целочисленному представлению символа `(который равен 96), вы получаете» привет мир «:
104 -> ч
101 -> е
108 -> л
108 -> л
111 -> о

119 -> ш
111 -> о
114 -> р
108 -> л
100 -> д

Почему вычитание этих двух раз (в 1927 году) дает странный результат?

В следующем вопросе пользователь анализирует две строки даты, ссылающиеся на раз в одну секунду, и сравнивает их.

01
02
03
04
05
06
07
08
09
10
public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    String str3 = "1927-12-31 23:54:07"
    String str4 = "1927-12-31 23:54:08"
    Date sDt3 = sf.parse(str3); 
    Date sDt4 = sf.parse(str4); 
    long ld3 = sDt3.getTime() /1000
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

Вместо того, чтобы получить результат 1, так как они находятся на расстоянии 1 секунды, он получает результат 353 (очередь жуткая музыка). Это имеет довольно простое объяснение: это вещь часового пояса. 31 декабря 1927 года шанхайское время переместилось на 5 минут и 52 секунды назад, и Java анализирует его как момент времени для этой локальной даты / времени.

Мы должны указать, что если вы попытаетесь запустить код из исходного вопроса, он даст другой результат. Как отметил в своем ответе Джон Скит , в проекте «База данных о часовых поясах 2014» время изменения сместилось на 1900–12–31, и теперь это всего лишь 343 секунды.

Неуловимый ChuckNorrisException

Это немного очевидный вопрос: если выдается исключение, но никто не может его перехватить, произойдет ли сбой приложения? Или, как задается вопрос: «Возможно ли создать фрагмент кода на Java, который бы сделал гипотетическое исключение java.lang.ChuckNorrisException неуловимым?».

Короткий ответ: это возможно, но в этом есть «но». Вы можете скомпилировать код, который выдает исключение ChuckNorrisException, и определить класс ChuckNorrisException, который не расширяет Throwable во время выполнения. Одного этого недостаточно, чтобы заставить его работать, и вам придется отключить проверку байт-кода. Ответ от Jtahlborn проведет вас через весь процесс.

Если вы фанат Java-головоломок, вы можете попробовать нашу игру Java Deathmatch .

5. Хеш-карты

Одна из наиболее распространенных проблем, с которыми мы столкнулись в Stackoverflow, связана с хэш-картами. Многие пользователи хотят знать, в чем разница между коллекциями и когда их следует использовать поверх других.

Ключевым компонентом здесь является порядок итераций. С HashMap у вас не будет информации о заказе, и этот порядок может измениться, если вы добавите больше элементов в свою коллекцию. С TreeMap вы получите отсортированную итерацию, а с LinkedHashMap вы получите FIFO-заказ.

Если вы все еще не уверены в этом, наши друзья в Rebel Labs составили удобный график, который объясняет преимущества одной коллекции над другой.

Последние мысли

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

Если вы натолкнулись на интересный вопрос, ожесточенные дебаты или другую причуду, мы хотели бы услышать об этом в комментариях ниже.