Полезные советы, спасибо автору.
Немного из моего опыта, не претендующую на истину в последней инстанции.
Я составляю резюме исключительно на английском, предварительно показывая его отлично знающему английский человеку. Это позволяет отсеять работодателей, чьи финансовые условия и проекты мне навряд ли понравятся.
Зарплату лучше указывать для уровней middle-senior и далее, по моему опыту так я действительно получаю самые интересные предложения. Я выставляю такую минимальную планку зарплаты, переход на которую мне был бы интересен. Обычно это текущая зп + %, зависящий от текущей ситуации на рынке труда. Это позволяет не отпугнуть потенциальных работодателей и себя тоже не обидеть. Жаль что на рекрутинговых сайтах не принято указывать вилку зарплат.
Ходить на собеседования, без желания сменить работу не вижу смысла:
1) потеря времени, потратить время на повторение core (в основном это спрашивают на собеседованиях) можно в любое время, а еще лучше подтянуть английский
2) фиксируется у работодателя текущий профессиональный уровень, в том числе финансовый, а ведь к моменту в будущем, когда реально нужно будет сменить работу, можно стать еще круче :)
> принесите на собеседование распечатанное резюме (лучше две копии или три)
Что мешает HR-специалисту распечатать нужное количество экземпляров резюме для всех собеседующих?
Ведь кандидат не в курсе, сколько может понадобиться копий.
Кроме того, у кандидата могут появиться проблемы с распечаткой и доставкой резюме: у кандидата может не быть принтера дома, а воспользоваться принтером текущего работодателя могут не позволить моральные убеждения, может не быть портфеля/папки чтобы принести резюме в не скомканном «товарном» виде.
> находить джуниора, учить и молиться, что он не уйдет через полгода на зарплату в два раза выше, чем ему платят
Джуниор осознанно работает за маленькую зарплату в надежде набраться опыта, а Вы осознанно платите ему маленькую зарплату, чтобы влезть в бюджет/найти спеца за высокую зарплату/себе. Все при своих законных интересах. Думаю если бы зарплата джуниора коррелировала с опытом (например после проведения внутренних добровольных тестов), то проблема утечки джуниоров была бы нивелирована.
Не сочтите за критику Вашей статьи, но некоторые вещи я посчитал необходимым объяснить.
> Важно не то, что ты сделал — важно то, что ты продал.
Весь бизнес ориентирован на получение прибыли, а значит на возможность продать некую фичу.
Важно находить в себе силы доказать менеджменту, что фича способна принести деньги, и эти деньги будут больше, чем затраты на разработку. В случае стартапа или личного дела будет то же самое, с той лишь разницей, что придется это доказывать только себе или партнерам.
> Последние версии ПО, ага, как же
В корпоративном секторе это обычное явление: работает и ладно, незачем менять, ведь переход на новую версию потребует дополнительных затрат на всеобъемлющее тестирование, что может быть весьма накладным. Приоритет для крупного бизнеса — бесперебойная работа существующих сервисов.
> 2-3 часа чистого кодинга в день — это замечательная цифра.
Программы становятся все сложнее, и пишутся многими людьми, сразу в них сложно разобраться, поэтому понимание чужой логики требует дополнительных затрат времени. Это неотъемлемая часть прогресса, если не будет придумано чего-то нового, который облегчит этот путь. Написание комментариев зависит от личных качеств человека, пишущего код.
ЕСВ в пенсионный в случае общей системы налогообложения (ОСН) не платится?
Какая процедура перехода на ОСН и возможен ли обратный переход в случае изменения ситуации?
Как можно временно приостановить деятельность СПД (при отсутствии деятельности) или не платить ЕСВ в пенсионный фонд, если он уже платится другим образом (например на официальной работе)?
Главное, не забыть всё правильно разметить, нужно вызвать валидатор, нужно сделать код для анализа результата и исправления возникшей проблемы.
А так очень хорошее средство, забыл про него упомянуть.
Я тут «переспал с мыслью» на эту тему :)
В будущей версии я создам отдельный аспект NullSafeAspectTotal, который как раз будет и поддерживать такую логику.
Нужный аспект оставляем в проекте, другой переименовываем, чтобы компилятор его не видел.
Есть одна проблема, которую мне пока не понятно как решить красиво:
При используемой сейчас lazy-инициализации объектов, в случае отсутсвия контруктора без параметров, такая инициализация будет производиться при каждом обращении. Как сделать так чтобы такая иницилизация была только один раз для каждого экземпляра?
Дмитpий, разрешите упомянуть Вас в главе «Благодарности» с будущей статье по этой теме?
Как я уже заметил в статье findbugs показывает, но не даёт решение сам.
findbugs — очень хороший инcтрумент в других случаях, и ничто не мешает использовать его совместно с NullSafeAspect.
прячем ошибку в логике, затрудняя её обнаружение. Возможно, к примеру, было бы лучше в «сеттере» бросать NPE если кто-то пытается туда передать null
Исключение еще нужно где-то перехватывать, лучше логирование без прерывания выполнения для выяснения проблем в логике.
Глючащая в одном маленьком месте программа гораздо лучше, чем плохо работающая программа вылетающая по исключению.
не боитесь распухания PermGen из-за большого количества классов, ведь ajc для каждого Around метода порождает класс. Или эту проблему как-то можно решить?
Из статьи: По умолчанию аспект создается в виде Singleton.
NullSafeAspect как раз такой.
One instance of the aspect is made. This is the default.
Многие сторонние библиотеки/фреймворки сами реализуют подобную логику, например реализации JPA.
В текущей реализации аспекты ограничены действием аннотации @ NullSafe, которую, по идее, вводят осознанно.
Реализация аспекта NullSafe по умолчанию статична, то есть может действовать только на исходные (то есть Ваши) тексты. Следовательно текущая реалилизация не затронет сторонние библиотеки, если для этого не предпринять дополнительных мер (см. Динамические аспекты или обобщение аннотаций аспектами).
Если синглтон без @ NullSafe, то логика аспекта работать не будет.
Принудительное наследование от abstract class Optional<T> уменьшит гибкость классов.
Аспекты таких ограничений не налагают, но как вариант существующих решений стоит упомянуть.
1) В классе помимо простых объектов String, Integer, Boolean и т.д. могут использоваться более сложные классы, например без конструктора без параметров.
2) Неиницилизированный сложный объект может быть вполне нормален с точки зрения логики программы.
Поэтому в таком случае я предпочитаю действовать точечно, в этом случае — с помощью аннотаций.
Вы можете переписать аспект под свои нужды, код проекта свободен для использования и модификаций (упрощённая 2-пунктовая BSD лицензия).
Поддержка Java Beans упомянута только потому, что при аспектной инициализации
@NullSafe
private SomeJavaBean bean;
нужен универсальный код инициализации через reflection, а требование наличия у Java Beans public конструктора без параметров как нельзя лучше к этому подходит.
Object obj=field.getType().newInstance();
Поэтому для данного аспекта сгодиться любой класс с конструктором без параметров…
Вторая причина упоминания Java Beans:
1) обеспечивает возможность прозрачного и без-проблемного увеличения функциональности бина за счет абстракции логики в get/set,
2) упомянутая Вами совместимость со средствами, активно использующими reflection и требующих стандартного стиля
именования, и таких средств очень много.
Можно конечно и так, но:
1) если strField используется внутри класса напрямую, то придется писать дополнительный «безопасный» код
2) не оптимально с точки зрения быстродействия, так идет сравнение на null в геттере, обычно операции чтения происходят чаще записи.
3) такой код нужно писать для всех таких полей, что просто неудобно
Принудительная инициализация и @ NullSafe(getter=false) — самый оптимальный путь с точки зрения быстродействия.
if (strField!=null){ this.strField=strField; } else { strField = ""; }
Я тоже думал над отождествлением null ещё и как пустого значения или 0, вместо нынешнего отбрасывания значения.
Мои соображения на этот счёт: если считать, что присваивание null является ошибкой, значит эта ошибка не должна влиять на целостность данных.
Я реализую предложенный Вами подход в виде аннотаций типа @ NullSafe(getter=false,nullIsValue=true), но это потребует некоторого времени.
Вы абсолютно правы: if(s!=null && !s.isEmpty()) является более оптимальным описанием этого выражения.
Но я ставил целью показать частоту и всеобщность использования проверки на null, поэтому намеренно разделил выражение для лучшего восприятия материала статьи.
Немного из моего опыта, не претендующую на истину в последней инстанции.
Я составляю резюме исключительно на английском, предварительно показывая его отлично знающему английский человеку. Это позволяет отсеять работодателей, чьи финансовые условия и проекты мне навряд ли понравятся.
Зарплату лучше указывать для уровней middle-senior и далее, по моему опыту так я действительно получаю самые интересные предложения. Я выставляю такую минимальную планку зарплаты, переход на которую мне был бы интересен. Обычно это текущая зп + %, зависящий от текущей ситуации на рынке труда. Это позволяет не отпугнуть потенциальных работодателей и себя тоже не обидеть. Жаль что на рекрутинговых сайтах не принято указывать вилку зарплат.
Ходить на собеседования, без желания сменить работу не вижу смысла:
1) потеря времени, потратить время на повторение core (в основном это спрашивают на собеседованиях) можно в любое время, а еще лучше подтянуть английский
2) фиксируется у работодателя текущий профессиональный уровень, в том числе финансовый, а ведь к моменту в будущем, когда реально нужно будет сменить работу, можно стать еще круче :)
Что мешает HR-специалисту распечатать нужное количество экземпляров резюме для всех собеседующих?
Ведь кандидат не в курсе, сколько может понадобиться копий.
Кроме того, у кандидата могут появиться проблемы с распечаткой и доставкой резюме: у кандидата может не быть принтера дома, а воспользоваться принтером текущего работодателя могут не позволить моральные убеждения, может не быть портфеля/папки чтобы принести резюме в не скомканном «товарном» виде.
> находить джуниора, учить и молиться, что он не уйдет через полгода на зарплату в два раза выше, чем ему платят
Джуниор осознанно работает за маленькую зарплату в надежде набраться опыта, а Вы осознанно платите ему маленькую зарплату, чтобы влезть в бюджет/найти спеца за высокую зарплату/себе. Все при своих законных интересах. Думаю если бы зарплата джуниора коррелировала с опытом (например после проведения внутренних добровольных тестов), то проблема утечки джуниоров была бы нивелирована.
А в остальном пост был поучительным.
> Важно не то, что ты сделал — важно то, что ты продал.
Весь бизнес ориентирован на получение прибыли, а значит на возможность продать некую фичу.
Важно находить в себе силы доказать менеджменту, что фича способна принести деньги, и эти деньги будут больше, чем затраты на разработку. В случае стартапа или личного дела будет то же самое, с той лишь разницей, что придется это доказывать только себе или партнерам.
> Последние версии ПО, ага, как же
В корпоративном секторе это обычное явление: работает и ладно, незачем менять, ведь переход на новую версию потребует дополнительных затрат на всеобъемлющее тестирование, что может быть весьма накладным. Приоритет для крупного бизнеса — бесперебойная работа существующих сервисов.
> 2-3 часа чистого кодинга в день — это замечательная цифра.
Программы становятся все сложнее, и пишутся многими людьми, сразу в них сложно разобраться, поэтому понимание чужой логики требует дополнительных затрат времени. Это неотъемлемая часть прогресса, если не будет придумано чего-то нового, который облегчит этот путь. Написание комментариев зависит от личных качеств человека, пишущего код.
Какая процедура перехода на ОСН и возможен ли обратный переход в случае изменения ситуации?
А так очень хорошее средство, забыл про него упомянуть.
В будущей версии я создам отдельный аспект NullSafeAspectTotal, который как раз будет и поддерживать такую логику.
Нужный аспект оставляем в проекте, другой переименовываем, чтобы компилятор его не видел.
Есть одна проблема, которую мне пока не понятно как решить красиво:
При используемой сейчас lazy-инициализации объектов, в случае отсутсвия контруктора без параметров, такая инициализация будет производиться при каждом обращении. Как сделать так чтобы такая иницилизация была только один раз для каждого экземпляра?
Дмитpий, разрешите упомянуть Вас в главе «Благодарности» с будущей статье по этой теме?
findbugs — очень хороший инcтрумент в других случаях, и ничто не мешает использовать его совместно с NullSafeAspect.
Исключение еще нужно где-то перехватывать, лучше логирование без прерывания выполнения для выяснения проблем в логике.
Глючащая в одном маленьком месте программа гораздо лучше, чем плохо работающая программа вылетающая по исключению.
Из статьи: По умолчанию аспект создается в виде Singleton.
NullSafeAspect как раз такой.
www.eclipse.org/aspectj/doc/next/progguide/quick-aspectAssociations.html
www.eclipse.org/aspectj/doc/next/progguide/semantics-aspects.html
Ajc для каждого Around-метода порождает вставку вызова функции статического внутреннего класса.
http://sidekick.windforwings.com/2009/06/aspectj-through-bytecode-examining.html
В текущей реализации аспекты ограничены действием аннотации @ NullSafe, которую, по идее, вводят осознанно.
Реализация аспекта NullSafe по умолчанию статична, то есть может действовать только на исходные (то есть Ваши) тексты. Следовательно текущая реалилизация не затронет сторонние библиотеки, если для этого не предпринять дополнительных мер (см. Динамические аспекты или обобщение аннотаций аспектами).
Если синглтон без @ NullSafe, то логика аспекта работать не будет.
abstract class Optional<T>
уменьшит гибкость классов.Аспекты таких ограничений не налагают, но как вариант существующих решений стоит упомянуть.
2) Неиницилизированный сложный объект может быть вполне нормален с точки зрения логики программы.
Поэтому в таком случае я предпочитаю действовать точечно, в этом случае — с помощью аннотаций.
Вы можете переписать аспект под свои нужды, код проекта свободен для использования и модификаций (упрощённая 2-пунктовая BSD лицензия).
@NullSafe private SomeJavaBean bean;
нужен универсальный код инициализации через reflection, а требование наличия у Java Beans public конструктора без параметров как нельзя лучше к этому подходит.
Object obj=field.getType().newInstance();
Поэтому для данного аспекта сгодиться любой класс с конструктором без параметров…
Вторая причина упоминания Java Beans:
1) обеспечивает возможность прозрачного и без-проблемного увеличения функциональности бина за счет абстракции логики в get/set,
2) упомянутая Вами совместимость со средствами, активно использующими reflection и требующих стандартного стиля
именования, и таких средств очень много.
1) если strField используется внутри класса напрямую, то придется писать дополнительный «безопасный» код
2) не оптимально с точки зрения быстродействия, так идет сравнение на null в геттере, обычно операции чтения происходят чаще записи.
3) такой код нужно писать для всех таких полей, что просто неудобно
Принудительная инициализация и @ NullSafe(getter=false) — самый оптимальный путь с точки зрения быстродействия.
if (strField!=null){ this.strField=strField; } else { strField = ""; }
Я тоже думал над отождествлением null ещё и как пустого значения или 0, вместо нынешнего отбрасывания значения.
Мои соображения на этот счёт: если считать, что присваивание null является ошибкой, значит эта ошибка не должна влиять на целостность данных.
Я реализую предложенный Вами подход в виде аннотаций типа @ NullSafe(getter=false,nullIsValue=true), но это потребует некоторого времени.
Но я ставил целью показать частоту и всеобщность использования проверки на null, поэтому намеренно разделил выражение для лучшего восприятия материала статьи.