Я хочу начать эту статью с необычного, на первый взгляд, отступления. Позже станет понятно, почему именно.
Начинаем с начала или 'Hello, Java World!' - 1
Итак, представим себе Некто. Этот Некто хочет освоить горные лыжи. И для этого он предпринимает следующие шаги:
  • Инструктора, учебники, пособия и т.п. — это всё от лукавого. Лыжи можно освоить самостоятельно. К тому же, в школе он сносно научился ходить на беговых лыжах. Соответственно, все советы более знающих людей игнорируются.

  • Снаряжение выбирается самое крутое. Не ниже уровня эксперта. Жесткие ботинки, от которых болят ноги. Жесткие лыжи, чтобы прогнуть которые нужно приложить фантастические усилия, далеко превосходящие уровень физической подготовки Некто. Ну и т. д.

  • В качестве пробной трассы выбирается... ну, скажем, трасса, принимающая этап кубка мира по гигантскому слалому. Для учебы это как раз.
  • Далее в том же духе.
Итак, вопрос. Как вы назовете этого Некто? Лично я, как человек, знакомый с горными лыжами уже около 20 лет, назову его (и это еще очень мягко!) — безнадежный. Научиться чему-нибудь при таком подходе невозможно совершенно. Зато верный способ покалечиться. И САМЫЙ верный — навсегда оставить идею встать на лыжи. Думаю, вы согласитесь со мной в такой оценке. В любом случае, я практически уверен, что ничего лицеприятного этот Некто в свой адрес не дождется. А теперь представим себе другого Некто. Пусть он, скажем, студент факультета информатики. Он имеет некоторое представление о С++, С#, Pascal. Он хочет изучить Java. Его действия:
  • Литература соответствующего его знаниям уровня (нулевого уровня, прямо скажем) отметается. На основании легкого знакомства с упомянутыми C++, C# и теорией ООП.
  • Берется самая мощная среда программирования. Скажем, Eclipse или NetBeans. Та, которая все делает сама, достаточно нажать одну кнопку.
  • В качестве пробного приложения выбирается... ну, скажем, чат. Приложение типа клиент-сервер, клиентская часть в виде апплета, серверная — веб-сервис или, на худой конец, сервлеты. Для учебы в самый раз.
Вопрос. Как вы назовете этого Некто? Знаете, в чем парадокс? В том, что в этом случае нелицеприятных оценок будет значительно меньше. При том, что ситуации по всем параметрам идентичны. Разве что последствия для здоровья и жизни во втором случае менее фатальны. Может, дело в этом? Ситуации действительно очень похожи. Я специально их описал в одинаковом стиле. И странное дело: если абсурдность первой очевидна, то второму сценарию следует пугающее количество начинающих разработчиков. Освоение Java начинают с написания мидлетов, клиентов для баз данных, чатов, создания сайтов на основе сервлетов... Продолжать можно долго. Но суть тем не менее очевидна. При этом литература начального уровня с пренебрежением откладывается в сторону. Читать это ? Мне? Да я на С++ вот уже три года пишу! (Варианты – на паскале, и даже на visual basic.) И ООП я знаю! Ну и вообще. И что дальше? А дальше вот что:
  • А как перевести массив из 8 байт в long?
  • А почему случается NoClassDefFoundError?
  • А почему я запускаю приложение в Eclipse (NetBeans/IDEA/JBuilder), и все в порядке, а без него я набираю java HelloWorld.class, а там ошибка?
  • А почему вылетает ClassNotFoundException?
  • А почему не находится библиотека? Я ее уже в classes.zip положил, а все без толку!
  • А почему я создаю массив объектов, а при попытке использования элемента массива получаю NullPointerException?
  • А почему ...?
  • А почему ...?
  • А почему ...?
Почему, почему, почему? А потому, что Java – это не С++ и не Паскаль. И не Perl. Знание этих языков не только чаще всего не помогает, но и мешает. Хотя бы потому, что у этих языков совершенно разная идеология. Но внешнее сходство вводит в заблуждение. Безусловно, на все эти "почему" и "как" есть ответы в книгах. В литературе самого начального уровня. Но читать ее – лениво (варианты – стыдно, некогда и т.п.). Я знаю достаточно много стереотипов, перенесенных в Java хорошими специалистами в С++. Один из недавних примеров: в конструкторе ни в коем случае нельзя бросать исключение. Почему? Да потому что в С++ состояние такого объекта не определено. Соответственно, возникает утечка памяти. В Java такой проблемы нет в принципе, ввиду наличия сборщика мусора. Однако находятся люди, которые стараются избегать таких ситуаций. Просто по укоренившемуся стереотипу. И хуже всего то, что в результате этих усилий сильно усложняется код. Изучить синтаксис несложно. И совершенно недостаточно. Идеология языка гораздо более важна. И для того, чтобы ее освоить наиболее эффективно, стоит начинать с самого начала. С чего именно и как? А это уже другой вопрос. Итак. С чего и как начинать. Это зависит от того, к чему вы хотите придти. Если вы хотите стать квалифицированной кодирующей обезьянкой – можно начинать практически с чего угодно. Если вы хотите стать профессионалом — тут всё несколько сложнее. Мой опыт дает мне основания утверждать следующее. Профессиональный разработчик отличается от "кодера" тем, что он понимает, что происходит. Он умеет несколько больше, чем нажимать кнопки. Мощная среда – очень хорошее подспорье. Для тех, кто может обойтись и без нее. Но она же – зачастую единственный инструмент тех, кто с нее начинал. И в ее отсутствие ценность кодирующей обезьянки равна нулю. Ибо кнопок, на которые надо нажимать, нет. Вообще, кнопконажимательство может принимать поистине чудовищные формы. Один из моих коллег видел продукт, написаный на Java. Инструкция по его установке начиналась словами:"Установите с диска JBuilder..." Вот ЭТО уже фатально. Если разработчики не смогли заставить продукт работать без среды разработки, то мне страшно подумать, как он был написан. По меньшей мере, его писали дилетанты. Что я подразумеваю под словами "понимает, что происходит". Это означает, что человек должен понимать следующее:
  • Что такое виртуальная машина и зачем она нужна.
  • Что такое класс с точки зрения виртуальной машины.
  • Что такое пакет.
  • Что такое библиотека.
  • Как виртуальная машина ищет и загружает классы; что такое загрузчик классов и как он работает; сколько их по умолчанию; что такое classpath.
И т.д. и т.п. Список можно продолжить. Заметьте, я не включил в него знаний, свойственных непосредственно разработчику. Что такое поток, что такое класс с точки зрения ООП и чем он отличается от объекта, как работают менеджеры компоновки – всё это обязан знать ЛЮБОЙ разработчик. Все, что я перечислил в списке – это скорее технические тонкости. Но очень часто оказывается, что их знание жизненно важно для понимания, что же работает не так. Пример из жизни. Есть такая библиотека для работы с XML, называется xalan. В ней присутствует несколько пакетов javax.xml... – парсеры, трансформеры и т.п. Библиотека эта очень популярна. Проблема в том, что эти же пакеты присутствуют в J2SDK, начиная с версии 1.4. Вопрос. Какой класс будет загружен при обращении из библиотеки к классу javax.xml.transform.stream.StreamSource, если в classpath присутствует и xalan – библиотечный или из J2SDK? Для ответа на этот вопрос необходимо знать, как работает загрузчик классов. Однажды я видел четырехдневное обсуждение в одном из форумов, упиравшееся в конечном итоге в этот вопрос. Код работал неверно именно из-за того, что загрузчик брал не тот класс, который от него ожидали. К чему я веду? Вот к чему: чем более мощная среда разработки, чем больше она делает за разработчика – тем меньше ему приходится думать. А это уже ой как плохо. Так недалеко и до обезьянки. Отсюда следует первый вывод, сколь парадоксальным бы он ни казался:

Вывод 1. Начинать изучение Java желательно БЕЗ мощной среды.

Я не призываю писать в редакторах уровня notepad. Но не делаю я этого по единственной причине – у них, как правило, не бывает подсветки синтаксиса. Это невероятно удобная вещь, не несущая отрицательного эффекта. Можно воспользоваться чем-нибудь типа Notepad++, он понимает синтаксис Java и, кстати, бесплатен. У меня, например, тип файла .java зарегистрирован в системе именно на него. Итак, текстовый редактор с подсветкой синтаксиса и командная строка. Два-три дня мучений – и понимание того, что такое classpath, как запускается интерпретатор и еще кучи разных мелочей – понимание этого останется навсегда. Далее. Мой опыт дает мне основания утверждать, что получить знания впрок невозможно. В том смысле, что читать литературу стоит лишь тогда, когда есть вопросы, на которые она даст ответ. Если читать книгу, не имея к ней вопросов, то информация выветрится через неделю. Я очень хорошо знаю это, в том числе и на своем опыте. Когда-то я раз пять принимался читать книгу по сервлетам. До тех пор, пока я не стал иметь с ними дела в работе, информация не усваивалась. И это далеко не единичный случай. Когда-то давно, очень давно, лет 8-10 назад, я прочитал следующее, к сожалению, не помню автора: Как научить человека новому языку программирования? Очень просто. Надо дать ему язык, несколько задач и минимум документации. Затем, по прошествии пары месяцев, когда он уже начнет худо-бедно писать на этом языке – дать исчерпывающую документацию. Она будет прочитана за две недели как детективный роман, после чего человек будет готов к работе. Я с этим утверждением согласен на все 100%. За два месяца, со одной стороны, уйдут все мелкие вопросы. Ответы на них будут получены самостоятельно, что сильно повысит их ценность. С другой стороны, уже сформируются ясные вопросы, ответы на которые даст именно документация. Отсюда следует второй вывод, кажущийся не менее парадоксальным, чем первый:

Вывод 2. Начинать изучение Java желательно БЕЗ учебников. Java API documentation + Java tutorial — этого более чем достаточно.

Java API documentation – вещь первой необходимости. Я очень советую держать ее локально, на диске. К ней придется обращаться не раз, не два и даже не десять. У меня лично не проходит ни дня, чтобы я туда не полез. Java tutorial я тоже советую держать локально. Это информация начального уровня, вполне заменяющая учебник. Однако ее там изрядно. Должен сказать, что в областях, с которыми я не имею дела по работе, я все ещё нахожу для себя что-то новое. Читать много — плохо. Пока нет запроса — нет и отклика. Читать мало — тоже плохо. Где золотая середина? Я придерживаюсь такого правила: читаю до тех пор, пока мне не начинает казаться, что я получил ответ на вопрос. В 90% случаев это не так. Но именно в этот момент лучше всего остановиться и продолжить самому. Исходный толчок получен, а самостоятельное решение задачи даст гораздо больше. Разумеется, по прошествии некоторого времени стоит взяться за литературу. Но опять-таки, за литературу начального уровня. Пусть даже кажется, что все это ерунда – прочитать начальные главы стоит. Я могу практически гарантировать, что хоть что-нибудь новое вы узнаете. И это что-нибудь впоследствии может оказаться необычайно важным. Ладно. В чем писать, вроде разобрались. Как писать — тоже. А вот что писать? Вспомните то, с чего начиналась эта статья. Стоит ли начинать с написания системы мгновенного обмена сообщениями? Выбирать, конечно, вам. Мне кажется — не стоит. Чем сложнее задача — тем больше вопросов возникнет. При отсутствии опыта такое количество вопросов даст ощущение невозможности их решения, дальше — ощущение собственной ущербности, глупости и т.п. В конечном итоге, это может привести к решению "а ну его на..." и прекращению изучения языка. Т.е. ровно к противоположному эффекту, чем тот, который был необходим. Это свойственно не столько Java, сколько процессу обучения как таковому. Но почему-то именно в приложении к обучению программированию об этом забывают. Между тем, небольшая задача, доведенная до конца, способна дать гораздо большее удовлетворение и гораздо большие знания, нежели грандиозная система, брошенная в самом начале пути. Отсюда — вывод третий: Вывод 3. Начинать изучение Java желательно c задач, адекватных имеющемуся уровню знания Java. Начинать учиться водить автомобиль не стоит на болиде Формулы 1. Начинать осваивать горные лыжи не стоит на трассе кубка мира. И точно так же не стоит начинать освоение Java с написания чего-то огромного. Я понимаю, амбиции требуют. Но в данном случае они необоснованы. А чем больше необоснованных амбиций — тем меньше шансов стать профессионалом. Замечательным в отношении обучения феноменом являются, как ни странно, различные форумы. Если ими пользоваться с умом. С умом – это означает, что надо поступать наоборот, не так, как привычно. А именно — не задавать вопросы, а отвечать на них. На любые, до которых есть силы дотянуться. Если вы думаете, что я сам знаю всё — вы сильно ошибаетесь. Да, я знаю много. Но есть области, с которыми я никогда не сталкивался. Или сталкивался, но крайне мало. Классический пример из моей практики — работа с сертификатами: подписывание кода, защищенные соединения и т.п. В 98-м году, при написании диплома, я это делал, но с тех пор все поменялось и сильно. В течение многих лет у меня накапливались вопросы. Я даже принимался читать какую-то литературу. Но, как я уже говорил выше, впрок знаний не получить. Это как лом – в одно ухо входит, в другое выходит. Результата никакого, кроме дырки в голове. И так продолжалось до недавнего времени, пока в форуме не задали вопрос об SSL-соединении с tomcat-ом. Проблемы какие-то были. И только вот этот вопрос подтолкнул меня закопаться глубоко. А раз есть запрос – есть и отклик. Я не только разобрался, в чем у человека проблема, но и нашел кучу другой полезной информации. Понял, наконец, как работают сертификаты. Соответствующая статья в планах. И такое – сплошь и рядом. Я достаточно мало работал, например, с GUI. Только в результате чьего-то вопроса в форуме я разобрался в некоторых возможностях TextLayout. До этого вопроса я о них не подозревал. Точно так же недавно я выяснил, что, оказывается JButton тоже интерпретирует html в качестве собственного заголовка. До этого я считал, что это умеет только JLabel. И это опять-таки благодаря форуму. Вот и получается: чем больше мы отвечаем на вопросы – тем больше узнаем сами. Именно потому я не согласен с расхожим мнением, что если человек сидит в форуме, то он ничего не делает. Это далеко не так однозначно и зависит прежде всего от того, зачем именно человек сидит в форуме. И что он делает преимущественно – спрашивает или отвечает. На самом деле можно даже спрашивать. Но тоже с умом. Не просить решения (а тем паче — с припиской "просьба тем, кто знает, дать ответ, а не задавать вопросы!", с чем я столкнулся буквально на днях!), а опять-таки наоборот — попросить задать направление движения. Совершенно понятно, что новичку сложно понять, где копать, ибо элементарно не хватает опыта. Это не вина человека, и даже не беда. Это – нормально. Через это прошли все. Я в том числе. Для меня лично гораздо важнее то, что человек хочет чему-то научиться. А не просто получить ответ, чтобы забыть его через пять минут после сдачи лабораторной по программированию. Направление движения я подскажу всегда. Если знаю его сам. А если не знаю – по крайней мере могу предположить. И уж точно буду тоже искать ответ. А вот прямых ответов я, пожалуй, не даю никогда – во всяком случае, не припомню. Кстати, именно из-за этого я ушел с одного из форумов. Когда я начал задавать наводящие вопросы, мне хором объяснили, что у них принято просто отвечать. А со своими вопросами я могу идти подальше. Учитывая, что уровень форума оставлял желать лучшего, – не в последнюю очередь благодаря такому подходу! – я решил больше не тратить времени. Так что выбирайте себе форум по вкусу – и в путь. Кстати, этот сайт появился именно благодаря одному из форумов. Пообщавшись там некоторое время, я накопил список наиболее часто поднимаемых тем и понял, что такой сайт будет востребован. Так и вышло. Практически все статьи написаны по следам каких-либо обсуждений в форуме. Или по следам переписки, которую я тоже веду регулярно. Каков же итог? Работать, работать и еще раз работать. Чем больше вы позволяете делать за себя на начальном этапе – тем меньше знаний вы получаете. И тем дольше дорога к профессионализму. Но только вы сами можете выбрать, кем вы хотите быть – бездумно нажимающей кнопки обезьянкой или профессионалом. И только вы сами выбираете путь, идя по которому вы можете достигнуть того или другого. Первый путь понятен. Второй я постарался показать. Ваш ход, господа! Ссылка на первоисточник: Начинаем с начала или 'Hello, Java World!'