mismatch
Java code
// Как жить без приватных методов в интерфейсах?
// Например, пишем такое в DefaultsInterface.java:
public interface DefaultsInterface {

	default void test1() {
		DefaultsInterfaceCompanion.INSTANCE.test("S1");
	}

	default void test2() {
		DefaultsInterfaceCompanion.INSTANCE.test("S2");
	}
}

enum DefaultsInterfaceCompanion {
	INSTANCE();

	void test(String suffix) {
		System.out.println("test" + suffix);
	}
}

// Да, замена не равноценная, но проблему дублирования кода 
// в дефолтных методах решает, не загрязняя интерфейс. 
mismatch
программирование What We Actually Know About Software Development, and Why We Believe It's True — видео актуальное и по сей день, в котором Greg Wilson рассказывает интересные факты о разработке ПО.
1. Грэг, ссылаясь на работу “Anchoring and Adjustment in Software Estimation”, говорит, что программисты дают ту оценку, которую вы ожидаете от них услышать, независимо от опыта разработки и знания предметной области. При этом не исследовано уменьшается ли итоговая погрешность оценки при разбиении задач на более мелкие.
2. Производительность программиста зависит от длины текста кода, решающего поставленную проблему
3. Большинство ошибок вносится еще до стадии кодирования, а стоимость исправления увеличивается тем больше, чем дольше ошибка остается необнаруженной. Адепты гибкой разработки оптимистически полагают, что стоимость исправления ошибок может быть уменьшена за счет коротких итераций (но это не доказано)
4. Зависимость сложности решения от сложности решаемой проблемы — нелинейная(при этом сложность решения растет быстрее).
5. Промахи в оценке и нестабильные требования — наибольшие проблемы в разработке ПО
6. Если вам предстоит изменить 20-25% компонента, то лучше переписать его с нуля
7. Качественное ревью кода помогает избежать от 60 до 90% багов. При этом оно должно длится не более часа. Размер кода, проходящего ревью, не должен превышать нескольких сотен строчек. Именно столько можно качественно проревьювить за час.

mismatch
программирование The deep synergy between testability and good design — еще один доклад от Майкла Физерса. И начинает он с того, что проблемы с тестированием кода сигнализируют о проблемах с дизайном этого кода. Например, если у вас возникает желание протестировать приватные методы класса, скорее всего он делает слишком много и не следует принципу единственной ответственности. Некоторых разработчиков смущает то, что следование этому принципу приводит к появлению большого количества небольших классов. Но так ли это плохо? Да, в определенных случаях вам придется походить по файлам, чтобы разобраться как работает некоторая функциональность. Но это разделение упрощает поддержку кода. В большинстве случаев вам будет достаточно заменить один из этих небольших классов или добавить еще один небольшой класс вместо того, чтобы менять один большой и беспокоиться не сломали ли вы существующую функциональность.
Далее Майкл задается вопросом: а что же затрудняет тестирование кода?
1. Спрятанное в методе состояние — у вас длинный метод с многими локальными переменными и вы хотите протестировать работу этого метода при различных комбинациях значений этих переменных
2. Сложная система — класс с многими зависимостями, необходимыми для его создания
3. Неполное выключение — например, не освобождаются ресурсы или не переводятся в нужное состояние. В этом случае появится зависимость между тестами и они начнут падать, сигнализируя об имеющейся проблеме.
4. Состояние перетекает из одного теста в другой — например, статическая изменяемая переменная или синглтоны
5. Наличие фреймворка — если фреймворк затрудняет тестирование, то вы недостаточно разделили фреймворк и предметную область
6. Сложности с моками — не нарушаете ли вы закон Деметра?
7. Скрытые эффекты
8. Скрытые входные данные — возможно вы перестарались с инкапсуляцией
9. Громоздкий список параметров метода — нарушение принципа единственной ответственности
10. Недоступность метода — этот случай рассмотрен в самом начале
11. Круговерть тестов — при изменении кода меняется много тестов — вы нарушаете принцип открытости/закрытости
mismatch
технический_долг Escaping the Technical Debt Cycle — Michael Feathers говорит о том, что важно концентрироваться не на количественных метриках, а на качественных. Не все можно измерить (попробуйте, подсчитать кол-во нарушений принципа подстановки Лисков в коде) и то, что вы измеряете и контролируете, не должно заменять здравого смысла. Важно не то, насколько красивые показатели у вашего кода, а то, насколько легко адаптировать его к изменяющимся требованиям. Исходя из этого Майкл определяет технический долг, как затраты на рефакторинг, после которого добавление новой функциональности будет безболезненным. Для оценки технического долга он предлагает использовать feature trend cards: напишите на карточках несколько воображаемых фич (не связанных с текущими задачами) и оцените время, необходимое для их добавления. Делайте это периодически и вы будете представлять размер долга. Второе предложение от Майкла — выделяйте подготовительный рефакторинг, необходимый для добавления новой функциональности, в отдельную задачу. Далее поручите выполнение этой задачи одним разработчикам, а добавление функциональности — другим. Такое разделение способствует общению между двумя группами и подчеркивает важность подготовительного рефакторинга. Но это разделение также имеет свою цену и не стоит проводить его регулярно.
Во второй части доклада Майкл задается вопросом: откуда же берется технический долг? Одной из причин он называет недостаточную прозрачность для бизнеса процесса разработки и недостаток понимания влияния желаемых изменений на существующую функциональность. Второй причиной он называет недостаток понимания качества текущего дизайна кода — насколько он хорош или плох.
mismatch
Java LinkedHashMap для LRU-кэша на коленке. Наткнулся здесь, а потом и в JavaDoc это нашел. Идея не новая, но всегда полезно вспомнить базовые вещи.
На практике я использовал CacheBuilder из Guava, а еще советуют Caffeine (но там, как я понял, другой алгоритм вытеснения элементов из кэша).
mismatch
devops В The Myth of the Root Cause: How Complex Web Systems Fail и Each necessary, but only jointly sufficient пишут о том, что при анализе падения, выхода из строя сложной системы не следует искать единую корневую причину. Анализируя произошедшее падение постфактум нам свойственно выделять одни события и недооценивать другие, а также неправильно выстраивать их во времени, путая причину и следствие. Также, когда объяснение требуют как можно скорее, нам свойственно упрощать и не докапываться до истинных причин. Нахождение единственной причины падения сложной системы сравнивают с поиском единственной причины успеха человека / бизнеса. На самом деле причин много, но каждая из них по отдельности не является достаточной, а только некоторая их комбинация. Надо перестать воспринимать сложную систему как линейную, а в нелинейной системе, как известно, даже небольшие отклонения значений ее параметров могут приводить к существенным изменениям всей системы. Утверждается, что сложную систему следует считать сломанной по умолчанию.
Опасность сведения падения системы к единственной корневой причине заключается еще и в том, что по результатам анализа обычно принимаются меры по недопущению предполагаемой причины повторно, которые сами по себе могут стать причиной следующего падения.