Pull to refresh
5
0
Джуниор @life_of_junior_dev

Java, карьера, жизнь

Send message

⌨️ КАСТОМНЫЙ МАППИНГ КЛАВИШ В ЛИНУКС: ПРЕВРАЩАЕМ IJKL В СТРЕЛОЧКИ

Для навигации в среде разработки я использую использую маппинг ijkl на стрелочки и оказывается можно сделать этот маппинг на уровне всей ос, а не только IDE.

Маппить будем с помощью xremap (подходит для Wayland и X, простая конфигурация в yaml, написан на расте).
Я буду показывать процесс настройки для федоры, но для других дистрибутивов он похожий.

🔧 Устанавливаем xremap из репозитория fedora copr

🔧 Создаем конфигурационный файл, который замапит клавиши ijkl на стрелочки при зажатом капсе:

virtual_modifiers:
  - CapsLock

keymap:
  - remap:
      CapsLock-i: Up
      CapsLock-j: Left
      CapsLock-k: Down
      CapsLock-l: Right
      CapsLock-h: Home
      CapsLock-semicolon: End
      CapsLock-u: PageUp
      CapsLock-o: PageDown

🔧 Тестируем работу с помощью команды:

sudo xremap /home/your-username/.config/xremap/config.yml

Если вам нужно определить название для клавиши запустите xremap в режиме дебага

sudo RUST_LOG=debug xremap /home/your-username/.config/xremap/config.yml

и нажмите эту клавишу.

🔧 Создаем сервис для работы xremap в фоне при запуске системы
Создаем файл с конфигурацией сервиса:

sudo nano /etc/systemd/system/xremap.service
[Unit]
Description=Start xremap

[Service]
Type=exec
ExecStart=xremap /home/your-username/.config/xremap/config.yml

Включаем сервис:

sudo systemctl daemon-reload
sudo systemctl start xremap.service

Включаем запуск xremap при старте компьютера:

sudo systemctl enable xremap.service

👨‍💻 Джуниор

Tags:
Total votes 3: ↑2 and ↓1+1
Comments1

🧠 БЕСПЛАТНЫЙ REASONING ИИ

Вы, возможно, слышали про perplexity - бесплатный, быстрый и довольно качественный ии-поисковик.
В нем есть возможность использовать модели "обдумывающие" ответ (Depseek R1, O3-mini и Perplexity Pro), но в день дается всего три таких запроса.

Оказывается, есть песочница, в которой думающая модель perplexity (sonar-reasoning) и дипсик (r1-1776) доступны без ограничений.

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

Тестируем
Я люблю тестировать модели вопросом "как отсортировать массив int в джаве в порядке убывания". Это вопрос с подвохом, потому что в джаве примитивы так сортировать нельзя.
Модель sonar-reasoning-pro дала правильный и развернутый ответ (не буду приводить код, только текст):

Для сортировки массива int в Java по убыванию есть несколько подходов, учитывая особенности работы с примитивными типами:
1. Сортировка через преобразование в Integer[]
Используйте обёртку Integer для массива и метод Collections.reverseOrder()
2. Сортировка по возрастанию + ручной разворот
Отсортируйте массив по возрастанию и переверните его

Почему нельзя использовать Comparator для int[]?
Метод Arrays.sort(int[]) не поддерживает параметр Comparator.
Примитивные типы (например, int) несовместимы с дженериками, которые используются в Comparator<T>.

Альтернатива для Java 8+:
Используйте Stream для работы с примитивами.

Важно:
Для небольших массивов разница в производительности между методами незначительна.
Если требуется сохранить исходный массив как int[], предпочтительнее второй метод (сортировка + разворот).

👨‍💻 Джуниор

Tags:
Total votes 2: ↑1 and ↓10
Comments2

⚡️ ПОЧЕМУ JAVA ТАКАЯ БЫСТРАЯ?

Есть много языков, которые не компилируется в машинный код, а исполняются на виртуальной машине или интерпритаторе - C#, Python, JavaScript и так далее, но самый быстрый из них Java.

😮 Почему?
В начале 2000-х на рынке JVM существовало несколько ключевых игроков:

  • Sun Microsystems HotSpot

  • IBM J9

  • Oracle JRockit

  • Excelsior JET

Но в декабре 2006 года, с выходом Java 6, HotSpot вырвалась вперед, разгромив конкурентов, благодаря JIT-компиляции.

🤔 Как работает JIT?
Just In Time компиляция — это механизм, который компилирует часто исполняющиеся участки кода в машинный код во время выполнения программы, что значительно ее ускоряет.

Рассмотрим метод:

public void exampleMethod(int value) {
    if (value > 0) {
        // Исполняется часто
        System.out.println("Positive value");
    } else {
        // Исполняется редко
        System.out.println("Non-positive value");
    }
}
  1. При первом вызове exampleMethod JVM интерпретирует байт-код

  2. Если exampleMethod вызывается многократно с положительными значениями, JIT-компилятор определяет это как "горячую точку"

  3. После достижения порога вызовов этой точки с условием value > 0 компилируется машинный код для метода

  4. Если позже будет вызван метод с отрицательным значением (что не ожидалось), произойдет uncommon trap, и управление передастся интерпретатору для обработки этого случая

☕️ То есть, JVM в рантайме определяет путь, который чаще всего проходит программа, и именно этот путь компилируется нативно и максимально оптимизируется.

⚡Благодаря такой оптимизации джава уничтожает бенчмарки, потому что в них обычно повторяется один и тот же код.

👨‍💻 Джуниор

Tags:
Total votes 12: ↑2 and ↓10-8
Comments4

🤔 Почему в джаве 128 != 128?

Такой код выведет false

Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1 == i2);

Тут все довольно просто, Integer - это объект, а не примитив и он хранится в хипе, поэтому сравнивать тут надо не по ссылке (через ==), а по значению - через i1.equals(i2).

А что выведет этот код?

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);

Тут вернется true.
Дело в том, что у оберток в джаве есть кэш.
Для Integer это [-128;127], поэтому все объекты интов от -127 до +128 равны и по ссылке и по значению.
Для интов размер кэша можно изменить через аргумент JVM XX:AutoBoxCacheMax=size

А что насчет такого кода?

Integer i1 = 127;
Integer i2 = new Integer(127);
System.out.println(i1 == i2);

Здесь будет false 🙂
При создании объекта через new мы создаем новый объект в хипе, который уже не будет равен по ссылке тому, что хранится в кэше.

Но так делать не стоит. Конструктор Integer(int) депрекейтнут.

👨‍💻 Джуниор

Tags:
Total votes 14: ↑14 and ↓0+20
Comments3

Избавляемся от хардкода в Java-приложении с @FieldNameConstants

Если вы работали с JPA Criteria API, то вам точно приходилось хардкодить название полей:

public Specification<Car> where(@Nullable CarFilterDto carFilter) {
    return (root, query, cb) -> cb.equal(root.get("type"), carFilter.getType());
}

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

@FieldNameConstants
public class FieldNameConstantsExample {
  private final String iAmAField;
  private final int andSoAmI;
  @FieldNameConstants.Exclude private final int asAmI;
}

и вот во что он превратится:

 public class FieldNameConstantsExample {
  private final String iAmAField;
  private final int andSoAmI;
  private final int asAmI;
  
  public static final class Fields {
    public static final String iAmAField = "iAmAField";
    public static final String andSoAmI = "andSoAmI";
  }
}

Также, можно:

  • генерировать енам вместо констант

  • поменять название статического класса

  • поменять уровень доступа полей

  • генерировать только для явно включенных полей

@FieldNameConstants(asEnum = true,
        innerTypeName = "StaticClassName", 
        level = lombok.AccessLevel.PRIVATE, 
        onlyExplicitlyIncluded = true)

👨‍💻 Джуниор

Tags:
Total votes 4: ↑3 and ↓1+2
Comments1

? Как успеть все на хакатоне

Прямо сейчас я еду домой со своего первого хакатона и хочу поделится впечатлениям и советами.

В общем, было очень сложно. За двое суток я спал всего 6 часов (по-моему, я первый раз в жизни так мало спал?‍?).

По ощущениям я работал супер медленно, много чего не успел и вот как этого избежать:

  • Сделать основу заранее. Шаблон проекта, базовые классы, дизайн, конфиги - все это лучше сделать до хакатона

  • Говнокод - наше все. Валидация идет нахрен, авторизация идет нахрен. ВСЕ, что заставляет вас писать больше кода ради красивой архитектуры - нахрен

  • Генерируйте! Для тестирования и документации мне очень сильно помогла генерация в open api

  • Очень четко ограничьте то, что надо сделать. Лучше меньше, но рабочее!

  • Если чего-то не знаете - разберитесь заранее. Авторизацию через тг я не успел, потому что планировал разобраться на месте

  • Ну и конечно выспитесь!!!

Tags:
Total votes 3: ↑2 and ↓1+3
Comments1

? Как убрать панель вкладок в Firefox

  1. В адресной строке введите about:config

  2. Измените toolkit.legacyUserProfileCustomizations.stylesheets на true

  3. В адресной строке введите about:support

  4. Откройте в проводнике папку, указанную в Profile Directory (Папка профиля)

  5. Создайте в ней папку chrome, в ней создайте файл userChrome.css

  6. Скопируйте в userChrome.css этот код

  7. Перезапустите Firefox

  8. Если вы хотите, чтобы вкладки были в боковой панели, установите Tree Style Tab

Зачем это делать?
Вкладки занимают очень много места (в комментариях до/после), а нужны они не всегда. Поэтому легче убрать их в сайдбар и открывать его горячей клавишей по необходимости.
Больше всего такой ux популяризировал Arc, но он есть только на мак, да и перелезать на другой браузер ради вкладок не хочется.

На firefox-csshacks, кстати, можно делать и другие комбинации стилей.
Например, вот обсуждение на редите, как убрать вкладки под панель поиска и сделать их растянутыми.

Tags:
Total votes 3: ↑3 and ↓0+4
Comments5

Почему в java нельзя отсортировать массив интов по убыванию?

Недавно решал задачку, предполагавшую сортировку int[] arr по убыванию.
Я пытался это сделать минут 5... Иии не отсортировал.

В джава нет вообще ни единого встроенного механизма сортировки массива примитивов по убыванию и вот почему.

Массивы сортируются с помощью метода Arrays.sort(arr), но сортирует он по возрастанию.
Для сортировки по убыванию нужно передать в него компаратор:

int[] arr = {1, 2, 3};
Arrays.sort(arr, (x, y) -> (y - x));

Не буду вдаваться в подробности работы компаратора, потому что такой код даже не скомпилируется! Компаратор не умеет работать с примитивами, ведь он использует дженерик:

public static <T> void sort(T[] a, Comparator<? super T> c);

А так выглядит sort для инта (и такой же метод есть отдельно для каждого примитива):

public static void sort(int[] a);

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

Tags:
Total votes 3: ↑3 and ↓0+3
Comments13

Продуктивность обычного студента ?

Учась в ВУЗе, я был не особо продуктивным, но со временем вывел подход, который сводит прокрастинацию к нулю.

Дано
И так, я обычный студент, проводящий почти каждый день дома?
У меня два ежедневных занятия: лабораторные и дипломный проект.

Решение
Прокрастинация появляется, когда теряется концентрация. Теряется она, когда задача кажется неподъемной.
Решение в том, чтобы фокусироваться не на задаче, а на времени выполнения. Таким образом, не важно насколько задача страшная, ее надо делать всего лишь час-два. Для этого нужно составить расписание.

Мое выглядело так:

  • 8.00 - 10.00: диплом

  • 10.00 - 11.00: лабы

  • 11.00 - 13.00: диплом

  • 13.00 - 14.00: обед

  • 14.00 - 15.00: лабы

  • 15.00 - 17.00: диплом

  • 17.00 - 18.00: лабы

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

Плюсы

  • Прокрастинация уходит почти в ноль. Постоянное переключение даже между двумя похожими задачами не дает расслабиться.

  • Контекст при переходе не теряется. В двух задачах потеряться сложно?

Минусы

  • Вырывать себя из одного контекста и помещать в другой очень трудно.

  • Не удается входить в состояние потока. Из-за частого переключения просто не хватает времени.

Tags:
Total votes 2: ↑2 and ↓0+2
Comments1

Проклятие дженериков 💀

Дженерики могут показаться очень простой темой.
Например, вот так в Java выглядят классные и простые методы интерфейса List:

interface List<E> extends Collection<E> {
	boolean add(E e);
	E set(int index, E element);
}

Но у обобщений много нюансов: вложенность, вариантность, границы и т.д. Это сильно усложняет их использование.
Вот не менее классный, но совсем непростой flatMap интерфейса Stream🙈:

interface Stream<T> extends BaseStream<T, Stream<T>> {
	<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
}

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

Из-за таких сложностей, в языке Go (философия которого - простота и минимализм) дженерики появились аж через 12 лет после релиза языка. А первый коммент про то что нужны дженерики появился меньше чем через 24 часа🙃

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

  • С++ вышел в 1979, дженерики - 1986

  • Java - 1996, дженерики - 2004

  • C# - 2001, дженерики - 2005

  • Go - 2009, дженерики - 2021

Tags:
Total votes 5: ↑3 and ↓2+1
Comments8

Information

Rating
Does not participate
Location
Барнаул, Алтайский край, Россия
Date of birth
Registered
Activity

Specialization

Backend Developer