Минутка просвещения

Читать в телеге. Когда-то там были посты не только от меня.

Рефлексия и продуктивность

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

  1. Состояние потока это важно, должно быть выделенное время для сосредоточенной работы
  2. Больше двух встреч в день — это рак, 1 встреча — норм.
  3. Даже оформление пулл-реквеста — это выход из потока.
  4. Больше времени в состоянии потока — больше достижений и меньше стресса.

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

Когда я впервые столкнулся с agile, я писал себе коротенько, что делал за день, чтобы потом на стендапе не надо было вспоминать. Но вскоре я, к сожалению, в этом разочаровался: увы, большинству людей абсолютно насрать, че ты там делал, проквакал че-то нормальное и пофиг. До agile я записывал только свои достижения. Вот это полезно, и я продолжаю везде это делать. На Performance Review ты молодец-огурец, кучу всего достиг и ничего не забыл. Да и в резюме есть что записать.

СсылкаКомментировать

"Понятность" java

Очень часто чуть ли не единственным техническим аргументом в пользу использования java, а не какого-нибудь высокоуровневного языка, слышу что-то вроде “ой, ну вот с этим синтаксическим сахаром ничего не понятно, вот на java все просто и логично, там легко читать и все понятно”.

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

СсылкаКомментировать

Ноутбук как монитор

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

Для создания виртуального экрана есть даже специальные HDMI-затычки и масса программных вариантов. Из них я попробовал 2:

  1. DeskPad — ноль настроек, запустил и готово. Но экран только один.
  2. BetterDisplat — настроек до фига. Но при запуске какого-то черта меняет настройки основного экрана. И хотя тут можно добавить больше одного виртуального экрана, я не разобрался, как сделать так, чтобы они не были зеркалом друг друга.

Шарил экраны с помощью Deskreen. Что тут сказать… вроде работает, но мыльно и тормознуто: лаг довольно заметен. Что интересно, я пробовал еще подключать iPad как третий монитор, и там лаг меньше. Еще совсем не помогало, что у личного ноута 16:10, iPad 4:3, а у мака вообще 1800x1169 — этот зоопарк либо обрезался, либо растягивался (возможно это можно настроить нормально, но из коробки работало так себе).

Столкнулся с проблемой, что окно не может быть на нескольких экранах одновременно, но оказалось, что это решается настройками мака. Кроме этого, было два случая, когда “все сломалось”:

  1. Когда в настройках мака сделал виртуальный экран основным, то маковский экран “завис”, а ноутный просто отвалился. Хорошо, что на iPad был запущен терминал, через который я прибил виртуальные экраны.
  2. Когда открыл окно на полный экран, мак сходит с ума и на своем экране показывает черноту, а на остальных получается либо статическая картинка, либо артефакты.

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

В общем, great idea, does not work.

СсылкаКомментировать

awk

Недавно понадобилось сделать простую операцию над текстовым файлом: посчитать минимальную/максимальную длину строки. Звучит элементарно, ща быстренько состряпаем что-нибудь из cat + wc + sort… Только надо подобрать правильную комбинацию параметров и xargs вставить. С наскока, разумеется, не получилось. На питоне ради этого писать лениво, и в итоге на StackOverflow было найдено решение с awk:

awk '{print length}' input.txt | sort -rn | head

На чистом awk минимум будет выглядеть так (решение предложено ChatGPT):

awk 'NR == 1 || length < min { min = length } END { print min }' input.txt

Еще проще будет посчитать среднюю длину строки:

awk '{total += length} END {print total/NR}' input.txt 

Раньше я обычно игнорировал решения на awk, потому что они были не очень понятны в отличие от различных комбинаций grep, sed, cut, wc, sort и прочих: они достаточно простые, и “делают одну вещь хорошо”. А если что-то серьезное возникало — то писал что-то на питоне.

Но после описанного случая решил немного почитать про awk и, оказывается, он из коробки поддерживает построчную обработку (питонячий бойлерплейт), разбивку на поля (cut) и регулярки (grep/sed). Достигается это за счет довольно интересной концепции: каждая строка проверяется по паттерну(ам) — условию/регулярке, и если она соответствует, то выполняется действие в фигурных скобках. В общем, планирую попробовать.

Хотя можно не париться и просто ChatGPT попросить скрипт написать.

СсылкаКомментировать

Сколько мониторов нужно для счастья

За время своей работы встречал разнообразные мнения по данному вопросу:

  1. Нужно 4 монитора! На одном реверсить, на другом даташит открыт, на третьем среда разработки, на четвертом разводка платы… Больше мониторов богу мониторов!
  2. Два монитора норм, на одном кодишь, на другом открыт тикет/чат/порнуха/унылый созвон. Или запускаешь созвон на одном экране, а другой шаришь.
  3. Нужен только один монитор (но большой), потому что если много мониторов — теряешь фокус на одной задаче.

Когда-то мне казалось, что надо 3 монитора, но сейчас я склоняюсь к умеренному варианту №2, причем это экран ноута + монитор. На одном большом экране даже со всякими приемами разделения окон может быть не очень удобно переключаться между контекстами (а на маке разделение экрана само по себе конченое). А двух экранов достаточно, чтобы выполнять переключение поворотом головы.

Вообще, переключение контекста — довольно дорогая операция. И если их нужно одновременно больше двух, то, возможно, вы что-то делаете не так? Может надо сделать какую-то предварительную обработку “вспомогательных” контекстов, чтобы они работали как один?

А что говорит по этому поводу наука? Нашел мета-исследование на тему (по DOI можно найти на сцихабе полный текст). Если смотреть на опросы пользователей, то там все понятно: минимум 17”, большинству подавай два монитора. Однако кто говорил, что ему надо четыре, не использовал их по полной. Если смотреть на более объективные измерения, то в одном исследовании измеренная продуктивность выше с двумя мониторами, чем с одним, но при этом третий монитор существенно на нее не влияет. В другом исследований не обнаружили разницу между одним и двумя мониторами 17” или 22” (зависит от задачи, в общем). При этом есть умеренные свидетельства уменьшения числа кликов/переключений окон при увеличении размера и количества мониторов.

СсылкаКомментировать

Работа с файловой системой

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

Правильно реализовать работу с символическими ссылками — довольно нетривиальная задача. Хорошую презентацию по этому поводу можно посмотреть тут. Если вкратце, то ссылки могут меняться между системными вызовами, что открывает массу возможностей для повышения привилегий из-за того, что их проверка и действие над ссылкой происходит неатомарно. Даже в системных вызовах Linux не смогли поправить это с первого и даже со второго раза.

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

В добавок к этому, я недавно нашел интересное поведение в java. Если создать папку, содержащую юникодные символы, то ее имя по-разному будет нормализовано в зависимости от того, был ли использован метод Files.createDirectory или File.mkdir. Это приводит к тому, что оригинальный путь не совпадает с “реальным” путем к файлу, который только что был создан по этому пути:

package test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.function.Function;


public class App {

    @FunctionalInterface
    public interface Action {
        void apply(Path path) throws IOException;
    }

    public static void main(String[] args) throws IOException {
        check("createDirectory", Files::createDirectory);
        check("mkdir", x -> x.toFile().mkdir());
    }

    private static void check(String hint, Action createDir) throws IOException {
        String name = "teŝt files";
        Path root = Path.of(name).toAbsolutePath();
        Path file = root.resolve("file1");

        Files.deleteIfExists(file);
        Files.deleteIfExists(root);
        createDir.apply(root);
        Files.createFile(file);

        Path alternative = file.toRealPath();

        System.out.printf("%s - Equals: %s, isSameFile: %s\n", hint, file.equals(alternative), Files.isSameFile(file, alternative));
    }
}

Вывод:

createDirectory - Equals: true, isSameFile: true
mkdir - Equals: false, isSameFile: true
СсылкаКомментировать

Запись команд терминала

Чтобы записать демонстрацию какой-нибудь последовательности команд, можно воспользоваться Asciinema. Работает примерно так:

Можно конвертировать результат в гифку или использовать js-проигрыватель.

На удивление, эта штука без проблем сработала, когда я ее запустил внутри самой себя. В целом прикольно, но мне текстовый формат нравится больше — оттуда, как минимум, проще копировать. Еще один минус — вся тупка при записи записывается, т.е. нет нормализации: задержки и ошибки при печати команд тоже сохраняются. С другой стороны, за счет этого запись более “живая”.

СсылкаКомментировать

Аннотации массивов в java

Психолог: заковыристые типы в Java не существуют, они не могут причинить тебе вреда.

Тем временем java: @Nullable List<? extends @Nullable Object> @NotNull [] @Nullable [] someVar.

Вьетнамские флешбеки от сишных указателей.

Если серьезно, то массивы всегда были “особенными”: вроде и не примитивы, но и не классы. Еще и куча исключений, настолько, что это в Kotlin просочилось.

СсылкаКомментировать

Двойные и тройные слеши в пути

Нашел прекрасное. В POSIX ////some/path, ///some/path и /some/path — это одно и то же, но при этом не то же самое что //some/path. 3 и более слешей спереди превращаются в одинарный слеш, а вот обработка 2 слэшей может зависеть от системы/реализации. И нет, это не из-за Microsoft.

В большинстве случаев, например в Cygwin, //host/path интерпретируется как сетевой ресурс. Но не сетью единой: например, в Bazel // используются для адресации таргетов.

СсылкаКомментировать