воскресенье, 30 апреля 2017 г.

Just run it

Пора написать что-то, что не относилось бы к программированию вообще, и к Java, в частности. Просто из-за большой нагрузки на работе не удается посвящать этому столько времени, скольхо хотелось бы - успеваю разве что пройти тест по Java раз в день и иногда немного почитать/послушать/посмотреть что-нибудь обучающее. Поэтому востребованным оказывается то, что требует меньше времени, а именно - физкультура и чтение книг по саморазвитию. Событие сегодняшнего дня - пробежка в лесу!
В лесу я не бегал с прошлого года, наверное, с сентября. Это было очень классно! Надо сказать, что за последний месяц мне удалось пройти 10 тренировок (громкое слово "бодибилдинг"), а потому тело хочет нагрузок. А хорошая погода стимулирует желание быть быстрым и легким. Сегодня все сошлось, и я доволен.

воскресенье, 12 марта 2017 г.

A programmer: Java #6: A a = new B();

Долго не мог разобраться с тем, что означает выражение

A a = new B(); // B extends A

Первый мой ответ на этот вопрос был таким:

Когда на объекте а вызывется метод, будет вызван тот его вариант, который переопределен в классе-наследнике. То есть:

Класс-наследник, кроме собственных методов, имеет все методы классов-родителей. Последние могут быть переопределны в классе-наследнике:

Пусть у класса А есть метод do() { // реализация для А};
И у класса В есть метод do() { // реализация для В}

Соответственно, в нашем случае - для a.do(); будет выбрана реализация для В:

Class Животное {
    издатьЗвук() {
        "Звук-Звук";
    };
}

Class Cобака extends Животное {
    издатьЗвук() {
        "Гав-Гав";
    };
}
Животное животное = new Собака();
животное.издатьЗвук();

Результат: "Гав-Гав".

Но возникал вопрос: а что в данном случае происходит с полями? Будут это поля из А или из В?

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

Но правильный ответ - нет, потому что в нашем случае объект а - это объект класса В, который приведен к типу А. Что это значит? Мне посоветовали читать "Философию Java", но хороший ответ нашел тут: "Преобразование типов".

Это значит, что если а - это объект класса В, то поля относятся к классу В. А "приведение ссылочных типов" означает только то, что в приведенном объекте не видны те поля, которых нет в классе-родителе (хотя они есть!). Следовательно, логика тут такая - обрезать то, чего нет в родителе, а в оставшихся полях будут значения из класса-наследника.

Другими словами, если у Животного не предусмотрен Хвост (а предусмотрен только у Собаки), то у нас будет Собака, которой нельзя использовать Хвост (хотя он есть). А если у Животного Хвост предусмотрен, то это будет Хвост Собаки.


UPD: На самом деле поля будут и от А, и от В. Но в случае прямого приведения типов ((А) а) поля от В будут скрыты (как если бы их не было). Другими словами Хвост будет не Хвостом Собаки, а Хвостом Животного.

На эту тему также посмотреть можно здесь, здесь, здесь и здесь.

понедельник, 6 февраля 2017 г.

A programmer: Time checking

Очень коротко о времени. Помнится, я собирался заниматься программированием 1 час в день (см.: A programmer: Time is experience). Как же обстоят дела спустя год?


В течении года были разные периоды. Например, иногда у меня по разным не получалось заниматься неделями и даже месяцами, и я очень переживал по этому поводу. С ноября я пошел на курсы, которые существенно активизировали работу, и поэтому смог наверстать упущенное. Таким образом, в итоге оказалось, что за 2016 год я потратил на программирование 384 часа (что больше, чем в среднем 1 час в день :)). Учитывая, что за этот год на данный момент я занимался 97 часов, а это почти 3 часа в день, то такая динамика мне весьма нравится. И дело не во времени как таковом - я вижу результат. Он, конечно, пока не такой, как хотелось бы, но я думаю, что около 20% того результата, при котором я мог бы чувствовать себя уверенным программистом (разумеется, при наличии постоянной практики - включительно), у меня уже есть. С одной стороны, получается, что, если динамика сохранится, то до 100% результата мне надо еще около 2 лет (а не 33 :) - уже хорошо). С другой, и динамика может измениться, и чувство уверенности прийти раньше, да и в не совсем уверенном состоянии тоже можно утверждаться в качестве программиста.

пятница, 6 января 2017 г.

A programmer: Java #5: Abstract and Final classes

Небольшая заметка для себя насчет abstract и final классов.

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

Final - класс, от которого нельзя наследоваться. Тем самым - нельзя переопределять его переменные и методы (то есть они неявно тоже final). Но создавать экземпляры такого класса можно.

Класс может быть одновременно и abstract, и final. В этом случае, соответственно, доступны только его собственные статические методы и переменные, поскольку, как было сказано, у abstract класса не может быть экземпляров.

понедельник, 2 января 2017 г.

A programmer: Java #4: Annotations


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

Когда я учился Java, я видел код — переменные, методы, циклы и прочее, а вот некоторых вещей не видел, и встретил впервые только на курсах. В числе этих невиданных штук были аннотации — это такие надписи со значком @. Очевидно, они для чего-то нужны. Иногда мне рассказывали, для чего, но вот как они работают, я понять не мог очень долго. Мне посоветовали написать аннотацию самому. Но результативно помочь мне в этом лучше всего остального смогла книга Уоллс К. Spring в действии. – М.: ДМК Пресс, 2013 и одно волшебное слово. Про книгу напишу в следующий раз, а про волшебное слово сейчас.

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

@MyAnnotation(здесь могут быть описаны параметры аннотации)

Аннотации основаны на механизме интерфейса, поэтому ключевое слово @interface и будет свидетельствовать о том, что это аннотация:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String info() default "";
int val() default 42;
}

Здесь @Target(ElementType.METHOD) и @Retention(RetentionPolicy.RUNTIME) указывают, что аннотация применима к методу и что она исполняется при выполнении программы, соответственно (разумеется, предусмотрены и другие опции). Для того, чтобы это работало, надо импортировать соответствующие пакеты:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

Как уже говорилось, значения описанных в аннотации переменных (если они иные, чем по умолчанию) могут указываться при применении аннотации.

Данная аннотация пока что только сообщает некоторую информацию, но большинство аннотаций «работают», что-то делают. Вот тут и была самая большая загвоздка для меня: где, собственно, реализация? Где находится кусок кода, который «встраивается» там, где аннотация должна выполнять какие-то действия. Я долго не мог этого понять, пока мне не посоветовали написать не просто какую-то аннотацию, а, например, аннотацию для валидации — то есть для проверки, правильно ли что-то введено пользователем (нет ли недопустимых значений и т.п. - если правильно, то ОК, если нет, то — вывод соответствующего сообщения, например).

Один из типичных примеров аннотаций для валидаций в коде выглядит так:
@Size(min=3, max=20, message="Username must be between 3 and 20 characters long.")
Когда я стал разбираться, как устроены аннотации для валидаций, то выяснилось, что, кроме обычных уже вещей, они содержат еще одну аннтоацию для аннотаций (вот заветное волшебное слово): @Constraint. После него и указывается файл, в котором и происходит соответствующая проверка:
@Constraint(validatedBy = BlaBlaBlaValidator.class)

То есть, кроме собственно аннотации надо написать соответствующий класс. Другое дело, что у стандартных аннотаций этот класс уже «встроен», как я понял.

Волшебное слово лучше всего описано здесь:
Spring MVC кастомная аннотация для валидации форм (http://devcolibri.com/2664)
и здесь:

Другие материалы по аннотациям:

1. Об аннотациях вообще:

 - The Java™ Tutorials. Lesson: Annotations (http://docs.oracle.com/javase/tutorial/java/annotations/index.html);
 - Аннотации в Java (http://www.quizful.net/post/annotations-in-java);
 - Аннотации в Java - Annotation Types (http://www.javenue.info/post/79);
 - Spring. Аннотации. Конфигурация с помощью аннотаций - 9 - The Basics of Spring Framework (Юрий Ткач) (https://www.youtube.com/watch?v=cIYUAKDnFo4&list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t&index=9);
 - Аннотации в Hibernate(http://java-course.ru/student/book2/hibernate-annotation/);
 - Как написать свою Аннотацию в Java? (http://devcolibri.com/1253);

2. Об аннотации @Autowired (как пример):

 - Использование аннотации @Autowired в Spring 3 (http://www.seostella.com/ru/article/2012/02/12/ispolzovanie-annotacii-autowired-v-spring-3.html);

3. Валидация:

 -  Проверка данных формы с помощью аннотаций (@Size, @Email и др) в Spring MVC (http://www.seostella.com/ru/article/2012/06/21/proverka-dannyh-formy-s-pomoschyu-annotaciy-size-email-i-dr-v-spring-mvc.html);
 - Spring. Проверка введенных данных (http://spring-projects.ru/guides/validating-form-input/);
 - Как создать собственный валидатор для Sping MVC (http://www.javacore.ru/topic/96-mvc-spring.htm);
 - Проверка входных данных Spring (http://src-code.net/proverka-vxodnyx-dannyx-spring/).


среда, 23 ноября 2016 г.

A programmer: Restart


Рестарт произошел в конце октября. В начале месяца я наткнулся на информацию о компьютерных курсах – точнее об открытом занятии, которые они проводили. К этому занятию было желательно сделать некоторое задание, для чего требовались некоторые предварительные знания и установка необходимого ПО. Курсы по Java, но суть их состоит не в обучении писать код как таковой, а в обучении процессу разработки в принципе. Важным конкурентным преимуществом является участие в настоящем проекте, для чего (кроме лекций и семинаров дважды в неделю) слушателям выделено место в коворкинге на один день в воскресенье (10 часов), а также постоянную помощь менторов в разных вопросах, связанных с проектом и обучением. В общем, на курсы я таки пошел. Не в последнюю очередь потому, что они начались именно сейчас: я могу заниматься с ноября по январь, а с февраля у меня начинается загруженный семестр на работе, поэтому не пойдя учиться сейчас, я, в сущности, терял бы около полугода, как минимум.


Поначалу курсы производили не вполне понятное впечатление, потому что мне пришлось настраивать технику и ПО, на что уходило немало времени, и включиться в работу сразу я не имел возможности. Сейчас процесс уже вроде бы пошел – я даже выполнил свое первое задание (сделал pull-request своего первого task’a). Погружение в работу – это хорошо, но сложно. Нужно не только знать, как собственно писать java-код, но и уметь работать с фреймворками (Spring, Hibernate), с GitHub'ом, с веб-тахнологиями (JSTL) и с базами данных (MySQL/Workbench). Поэтому часто не знаешь, за что хвататься, времени нет и т.д. Пока что я пытаюсь разбираться с логикой работы того, что уже сделано (как с образцом), активно советуясь с коллегами и менторами – это само по себе важный навык, который я стараюсь совершенствовать. Как и дисциплинировать самого себя.

Отчасти это удается – по крайней мере, в том, что к концу ноября получается наверстать долги по времени, накопившиеся с июля (имея в виду необходимость работать, минимум, 1 час в день, то есть 30 часов в месяц). Так, например, к октябрю долг был 135 часов, отработал 52, к ноябрю осталось 103 (30+73) часа, а к 22 ноября из них уже отработал 87. Таким образом, итого получается 265 часов. О содержательных вещах напишу потом.

вторник, 26 июля 2016 г.

A programmer: Steve Jobs and consumer society

Прочитал биографию Стива Джобса (Айзексон В. Стів Джобс. – Брайт Стар Паблішин, 2014. – 608 с.) Пересказывать, разумеется, не буду, мне важны некоторые ключевые принципы и наблюдения.


Если смотреть на развитие компьютерной индустрии достаточно абстрактно, то мы увидим две основные стратегии – либо делать программный продукт доступным для работы на самых разных устройствах, а потому и открытым для модифицирования (Microsoft), либо максимально заточить его только для «своего» устройства, запретить распространение вовне и исключить возможности вмешательства в него (Apple). Вроде бы обе стратегии имеют право на существование, что подтверждается успехами и Apple, и Microsoft. Причем, по степени распространенности Microsoft (как теперь и Android) более успешен. Поэтому возникает вопрос, зачем в условиях, когда все очень быстро меняется и требует постоянного апгрейда, делать закрытую систему, как это делал Стив Джобс?

Дело в том, что Стив Джобс видел свою задачу не в том, чтобы создать успешный бизнес, а в том, чтобы «создать ВЕЩЬ» – некий совершенный продукт. В этом он реализуется как творец, поэтому ему принципиально важно «управлять впечатлением», а поэтому он и закрывает возможности для стороннего вмешательства в свой продукт. Как оказалось, такой подход прекрасно подходит именно для современного мира потребления. Количество ядер, памяти или тактовая частота процессора, столь значимые для «профессионала» играют теперь меньшую роль по сравнению с эргономичностью формы, цветом, текстурой и т.п. Другими словами, когда внутренние технические характеристики перестали иметь такое принципиальное значение, на первый план вышли удобство, эстетические и символические аспекты, а именно их Джобс и ставил всегда во главу угла.

И еще кое-что – небольшая цитата из книги:

«То було для мене справжнім відкриттям. Ми всі були в цих мантіях, і нам подали турецьку каву. Професор пояснив, що кава готувалася геть не так, як у інших місцях, і тут мене осінило: «Яке з біса кому діло?». Та підліткам, навіть у Туреччині, до дупи та турецька кава. Весь день я спостерігав за молодими людьми в Стамбулі. Вони пили те саме, що будь-які інші підлітки в цілому світі, і носили одяг, який виглядав точнісінько так само, як той, що ми купили в Gap, і всі вони користувалися мобільними телефонами. Вони були такими ж, як і інші підлітки будь-де. Мене вразила думка, що для молодих людей цілий світ – однаковий. Коли ми випускаємо продукти, то вже немає чогось такого, як турецький телефон, чи то музичний програвач, який молоді люди в Туреччині хотіли би бачити відмінним від інших плеєрів, котрі використовуються в інших країнах світу. Тепер ми просто один світ» (с. 544).