tag:blogger.com,1999:blog-67978396242443446302024-03-06T10:21:39.651+02:00Yuriy Tkach BlogA blog on software engineering, programming technologies, application design, and just simple, but yet interesting life problems.Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.comBlogger29125tag:blogger.com,1999:blog-6797839624244344630.post-80325001176489524472016-10-28T20:36:00.000+03:002016-11-09T20:35:03.063+02:00Курс Spring Framework - The Basics<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqxqWKi-1JKfINjPkXKyomORiWOcmo39l99rkjJGXJe4h57IYVfjnqAZ9s7RUZJk7XuSVhaeJLwATHmWwtIPF3G21EhA_rzBfNcr7PJbcIe41XXf_wKmL8UVFekFB2IW_6k5bRcfmQdO0/s1600/Spring_Interview_Questions.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqxqWKi-1JKfINjPkXKyomORiWOcmo39l99rkjJGXJe4h57IYVfjnqAZ9s7RUZJk7XuSVhaeJLwATHmWwtIPF3G21EhA_rzBfNcr7PJbcIe41XXf_wKmL8UVFekFB2IW_6k5bRcfmQdO0/s200/Spring_Interview_Questions.png" width="200" /></a></div>
Когда-то давно я создал и вёл курс по основам Spring Framework. Это было где-то одновренно с <a href="http://blog.yuriytkach.com/2013/06/advanced-java-courses.html" target="_blank">курсами по Advanced Java</a>. Однако запись курса была в плохом качестве, и поэтому я его не выложил. Чуть позже с помощью компании, где я работаю, мы создали <a href="https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%81%D1%81%D0%BE%D0%B2%D1%8B%D0%B9_%D0%BE%D1%82%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D0%B9_%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD-%D0%BA%D1%83%D1%80%D1%81" target="_blank">MOOC</a> курс, записав его в студии. Также, я его нормально структурировал, добавил домашнее задания, проверочные тесты и т.п. В общем, всё, чтобы плодотворно учиться. К сожалению, по определенным причинам я не смог его тогда дооформить для youtube и выложить. И вот наконец, этот день настал :)<br />
<br />
Данный курс знакомит с базовыми концепциями Spring Framework и его основными модулями: Core, AOP, JDBC. С помощью практических примеров объясняется внедрение зависимостей (dependency injection), определение объектов (beans), их связывание. Курс учит различным способам конфигурации Spring, а также показывает базовые приемы использования базы данных и аспектов (aspects), языка выражений (expression language) и аннотаций.<br />
<br />
<a href="https://www.youtube.com/playlist?list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t" target="_blank">Курс</a> состоит из 13 видео-уроков (хо-хо, 13!), темы которых такие:<br />
<br />
<ol>
<li><a href="https://www.youtube.com/watch?v=3wBteulZaAs&index=1&list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t" target="_blank">Spring Architecture</a></li>
<li><a href="https://www.youtube.com/watch?v=IBNQ6whVHeI&index=2&list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t" target="_blank">Dependency Injection</a></li>
<li><a href="https://www.youtube.com/watch?v=y-obHCFTbZ4&list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t&index=3" target="_blank">Bean Naming and Context Start-up</a></li>
<li><a href="https://www.youtube.com/watch?v=kvcFK7criFc" target="_blank">Scopes and Inner Beans</a></li>
<li><a href="https://www.youtube.com/watch?v=ygaboLsCKA4" target="_blank">Initialize and Destroy</a></li>
<li><a href="https://www.youtube.com/watch?v=WQQlskveWyU" target="_blank">Context Features</a></li>
<li><a href="https://www.youtube.com/watch?v=kzkh5gF_fCs" target="_blank">Property Injection</a></li>
<li><a href="https://www.youtube.com/watch?v=ocAgKTnPpPQ" target="_blank">More Context Features</a></li>
<li><a href="https://www.youtube.com/watch?v=cIYUAKDnFo4" target="_blank">Configuration with Annotations</a></li>
<li>E<a href="https://www.youtube.com/watch?v=rWNy-PPp9Xo" target="_blank">xpression Language</a></li>
<li><a href="https://www.youtube.com/watch?v=aNcTL9e7luM" target="_blank">Aspect-Oriented Programming</a></li>
<li><a href="https://www.youtube.com/watch?v=DU_RWWk8mAY" target="_blank">Simple Aspects</a></li>
<li><a href="https://www.youtube.com/watch?v=2fAhdDwjRSA" target="_blank">Simple DB Access</a></li>
</ol>
<br />
Повествование идет на русском языке, слайды на английском - в конце-концов без него никуда. В этот раз я также добавил субтитры в видео на двух языках. После каждого видео-урока я предлагаю пройти небольшой тест (5-6 вопросов), чтобы просто проверить, как Вы усвоили материал. Вопросы теста на английском :) Ссылка на тест есть в описании к каждому видео.<br />
<br />
Как и с курсами Advanced Java, видео-уроки расчитаны на практику. Т.е. предлагается параллельно слушать и писать код. Также, в конце курса будет домашнее задание, где надо будет написать небольшое приложение, приближенное к реальному. На самом деле, домашних задания будет три: по темам 1-10, 11-12, и 13.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvxl3X5Ddazda2y4u5vYwJfN7Zs6Waer4jwnzb4aUsXYS2SwH4nIHAMH65l50Vo41i3ILOVtnWAIGeETylXX-gEfnbecYmHbpS9DPdkzhfi_xxRuKJMgqzyDFRWaI_swhCevobCPP5pno/s1600/P1230750.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvxl3X5Ddazda2y4u5vYwJfN7Zs6Waer4jwnzb4aUsXYS2SwH4nIHAMH65l50Vo41i3ILOVtnWAIGeETylXX-gEfnbecYmHbpS9DPdkzhfi_xxRuKJMgqzyDFRWaI_swhCevobCPP5pno/s320/P1230750.JPG" width="320" /></a></div>
Внимательный читатель тут может сказать: "Аха! А ведь уже были <a href="http://blog.yuriytkach.com/2009/11/spring-framework.html" target="_blank">лекции по Spring Framework</a>!" Да, лекции были. Но то были только лекции :) В этот раз, информации больше, плюс практика и еще раз практика. И сразу отвечу на вопрос, почему нет еще больше информации. А как же web, security, и другие фишки? Нет, по двум причинам. Во-первых, по другим темам курс я не создавал. Во-вторых, для новичка сложнее всего понять базу. Если он её осилит, то дальше и самостоятельно сможет. :)<br />
<br />
<br />
Как Вы уже, наверное, знаете, Spring Framework - это один из самых популярных фреймворков для разработки приложений на языке программирования Java. Он обеспечивает всестороннюю поддержку инфраструктуры при создании приложений, и используется миллионами разработчиков по всему миру. Знание Spring является полезным для понимания концепции внедрения зависимостей и способов управления объектами в любом приложении.Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com6tag:blogger.com,1999:blog-6797839624244344630.post-61084023975404794732014-02-05T23:12:00.001+02:002014-02-05T23:13:56.089+02:00Очень кратко об алгоритме сортировки в Java<!-- Place this tag in your head or just before your close body tag. -->
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<!-- Place this tag where you want the widget to render. -->
<div class="g-post" data-href="https://plus.google.com/105338712258087201801/posts/VvcnWwAdEif"></div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com0tag:blogger.com,1999:blog-6797839624244344630.post-57636183296268676022013-09-19T18:02:00.002+03:002013-09-19T18:02:51.274+03:00Многопоточные коллекции в Java<span style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAPCUS2Ebm7YcTw-OtwD3JkAQB6BSaIGjfY9tj3PUvk2UqrPUvu8bvGyk8uS3EJGKhiZIu1oIVBF6mqvnOJf1t5GZPEtZuTN-EAYMVyumFSBq65IYJObkSTbVQcPHYwaBZTImysLVOOUc/s200/msterdam.jpg" width="200" /></span>Начиная с версии Java 5 в пакете <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html" style="font-family: 'Courier New', Courier, monospace;" target="_blank">java.util.concurrent</a><span style="font-family: inherit;"> </span>появились реализации коллекций для эффективной работы в многопоточных приложения. Эти коллекции используют различные неблокирующие алгоритмы для достижения высокой скорости чтения/записи значений. Синхронизированный доступ происходит крайне редко и в целом не влияет на производительность. Почти. В зависимости от реализации. :) Рассмотрению таких коллекций посвящен данный урок.<br />
<br />
Со списками все просто: единственная существующая concurrent реализация - это <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">CopyOnWriteArrayList</span></a>. Из названия можно догадаться, как она работает - при изменении создается новая копия списка и, соответственно, происходит блокировка. При чтении блокировок нет. Следовательно, при частых операциях записи или удаления элементов работать будет медленнее, чем даже <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList(java.util.List)" target="_blank"><span style="font-family: Courier New, Courier, monospace;">Collections.synchronizedList()</span></a>, в котором блокируются все операции, но при этом нет копирования списка. На данном уроке Вы сможете на практике увидеть скороть и медлительность работы этой реализации. Вы напишите мультипоточное приложение, которое определит время чтения/записи значений в разные конкурентные списки.
<br />
<br />
Учитывая особенности работы <span style="font-family: Courier New, Courier, monospace;">CopyOnWriteArrayList</span>, имеет смысл выбирать данную реализацию, только если Вам действительно необходим индексный доступ к элементам, либо в коллекции возможно хранение дубликатов. Данное утверждение справедливо не только к мультипоточным реализациям, а к любым спискам вообще. Если же элементы в коллекции уникальны, и Вам достаточно последовательного доступа, тогда вполне подойдет <span style="font-family: Courier New, Courier, monospace;">Set</span>.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVyTZcMejiwecfGWwElcEXJQVYnr9Bx2vAv1KbqNGXoT4jdQhI-D6JO2EX4quPN5FdJxSR0N7dnUb_2p1N9DaLgVmbr_rWdN5YZp5E4b4DNc-0YZeeMGYvhvkYOrHexJUoM7qSpbGNEp0/s1600/skipList1.png" /></span></div>
Concurrent реализаций интерфейса Set существует две. Первая - это <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArraySet.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">CopyOnWriteArraySet</span></a>. Свойства такие же, как и у аналогичного списка. Вторая реализация - это <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListSet.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">ConcurrentSkipListSet</span></a>. Последняя основана на интересной структуре данных - слоёный список (<a href="http://en.wikipedia.org/wiki/Skip_list" target="_blank"><span style="font-family: Courier New, Courier, monospace;">SkipList</span></a>). Подробнее на русском языке Вы можете прочитать <a href="http://algolist.ru/ds/s_skl.php" target="_blank">на algolist.ru</a> и <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D1%81_%D0%BF%D1%80%D0%BE%D0%BF%D1%83%D1%81%D0%BA%D0%B0%D0%BC%D0%B8" target="_blank">википедии</a>. Я скажу лишь, что она представляет собой связный список, где вставка и удаление элементов происходит достаточно быстро. Такая структура данных также хорошо подходит для неблокирующего доступа несколькими потоками, ведь, например, для вставки достаточно заблокировать изменение двух соседних элементов в связном списке. В дополнении ко всему, набор <span style="font-family: Courier New, Courier, monospace;">ConcurrentSkipListSet</span> хранит значения в отсортированном виде, реализуя интерфейс <a href="http://docs.oracle.com/javase/7/docs/api/java/util/NavigableSet.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">NavigableSet</span></a>. При этом, конечно, не стоит забывать о <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">Comparator</span></a>-е, который будет сравнивать элементы, или интерфейсе <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">Comparable</span></a>, который они могут реализовывать.
<br />
<br />
Для использования Map в многопоточной среде существуют два класса - <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListMap.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">ConcurrentSkipListMap</span></a> и <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">ConcurrentHashMap</span></a>. Первая реализация подобна аналогичной для <span style="font-family: Courier New, Courier, monospace;">Set</span>. Вторая подобна <span style="font-family: Courier New, Courier, monospace;">HashMap</span>, где все пространство значений разбито на независимые области, каждая из которых представляет собой <a href="http://algolist.ru/ds/s_has.php" target="_blank">хеш-таблицу</a>. При вставке элемента блокируется только одна область, позволяя параллельные чтение/запись в другие области. Используя этот класс, необходимо помнить о занимаемой памяти, так как для эффектиной работы с несколькими потоками, количество и размеры этих областей <a href="http://ria101.wordpress.com/2011/12/12/concurrenthashmap-avoid-a-common-misuse/" target="_blank">быстро растут</a>. Еще одним полезным свойством обоих этих <span style="font-family: Courier New, Courier, monospace;">Map</span> есть то, что они реализуют интерфейс <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentMap.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">ConcurrentMap</span></a>. В нем представлены методы на основе неблокирующих алгоритмов, позволяющие безопасным образом выполнять проверку и изменение значений в рамках одной атомарной операции. Подобным образом работают атомарные переменные, такие как <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">AtomicInteger</span></a> и др. Подробнее о них я рассказывал на <a href="https://www.youtube.com/watch?v=g7ynfDFoCL4&list=SP6jg6AGdCNaXo06LjCBmRao-qJdf38oKp&index=2" target="_blank">втором уроке из курса Advanced Java Concurrency</a>.<br />
<br />
В качестве домашнего задания для данного урока предлагаю добавить немного “параллелизма” в приложение, <a href="http://yuriytkach.blogspot.com/2013/07/map-interface-implementations.html#hometask" target="_blank">написанное для предыдущих уроков</a>:
<br />
<br />
<ul style="margin-bottom: 0pt; margin-top: 0pt;">
<li>Во-первых, добавьте параллельную загрузку всех праздников в отсортированный <span style="font-family: Courier New, Courier, monospace;">Set</span>. Прочитав файл с помощью <a href="http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#readLines(java.io.File,%20java.lang.String)" target="_blank"><span style="font-family: Courier New, Courier, monospace;">org.apache.commons.io.FileUtils.readLines(file, encoding)</span></a>, передайте различные области списка нескольким потокам, которые будут парсить праздники и добавлять их в <span style="font-family: Courier New, Courier, monospace;">Set</span>.
</li>
<li>Во-вторых, одновременно с загрузкой и парсингом праздников выполните подсчет количества праздников для каждого дня и каждого месяца. Для этого используйте отдельные <span style="font-family: Courier New, Courier, monospace;">Map</span> для хранения того, сколько праздников будет в каждом дне и каждом месяце.</li>
<li>
В результате выполнения программы выведите наиболее и наименее “праздничный” день, а также количество праздников в каждом месяце.
</li>
</ul>
<br />
Ну и, конечно, видео данной урока:<br />
<br />
<center>
<iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/-yQeYo32Lt4" width="640"></iframe>
</center>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com1Kiev, Kyiv city, Ukraine50.4501 30.5234000000000388.8050509999999989 -52.093787499999962 90 113.14058750000004tag:blogger.com,1999:blog-6797839624244344630.post-20333686749971408532013-07-20T23:45:00.000+03:002013-07-20T23:45:22.546+03:00Интересные реализации интерфейса Map в Java<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheU4Waj5ykYMowp6mYJjCIxveOdxMigrBw0-8Pyp9WArRVTysFRRYvw5hr0dzuQ3ZxmGk5B0-h-6sG__KwO6BYKr_2SRnfvSN_ChZCW4uEZ_vlZAWJFuFi575whepdDKpTBnJsKi7mD4Y/s1600/Cat-in-a-Box.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheU4Waj5ykYMowp6mYJjCIxveOdxMigrBw0-8Pyp9WArRVTysFRRYvw5hr0dzuQ3ZxmGk5B0-h-6sG__KwO6BYKr_2SRnfvSN_ChZCW4uEZ_vlZAWJFuFi575whepdDKpTBnJsKi7mD4Y/s320/Cat-in-a-Box.jpg" width="320" /></a></div>
У интерфейса <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Map.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">Map</span></a> из <a href="http://en.wikipedia.org/wiki/Java_collections_framework" target="_blank">Java Collections Framework</a> есть несколько реализаций, и у некоторых из них есть очень интересные свойства, знание которых поможет Вам эффективно решать определенные задачи. Отличия между двумя распространенными реализациями - <span style="font-family: Courier New, Courier, monospace;">HashMap</span> и <span style="font-family: Courier New, Courier, monospace;">TreeMap</span> - такие же, как между <span style="font-family: Courier New, Courier, monospace;">HashSet</span> и <span style="font-family: Courier New, Courier, monospace;">TreeSet</span> (тем более, что последние реализованы на основе первых), и про них я <a href="http://yuriytkach.blogspot.com/2013/07/hashset-and-treeset-use.html" target="_blank">уже рассказывал</a>. В этом видео, я остановился на не-concurrent классах, таких как <span style="font-family: Courier New, Courier, monospace;">LinkedHashMap</span>, <span style="font-family: Courier New, Courier, monospace;">EnumMap</span>, <span style="font-family: Courier New, Courier, monospace;">WeakHashMap</span>.<br />
<br />
С <a href="http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">LinkedHashMap</span></a> все просто - получаете преимущества поика по хэш коду и, в дополнение к этому, порядок элементов при итерации будет таким же, как при вставке. С помощью конструкторов этого класса можно задать некоторые параметры, которые будут влиять на скорость работы, объем занимаемой памяти, а также на порядок элементов при итерации. Последнее особенно интересно, так как позволяет использовать <span style="font-family: Courier New, Courier, monospace;">LinkedHashMap</span> в очень интересных решениях, одно из которых - простейший <a href="http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%BA%D1%8D%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F#Least_Recently_Used_.28.D0.92.D1.8B.D1.82.D0.B5.D1.81.D0.BD.D0.B5.D0.BD.D0.B8.D0.B5_.D0.B4.D0.B0.D0.B2.D0.BD.D0.BE_.D0.BD.D0.B5.D0.B8.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D1.83.D0.B5.D0.BC.D1.8B.D1.85.29" target="_blank">LRU-кэш</a>.<br />
<br />
С <a href="http://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">EnumMap</span></a> все еще проще - обычный <span style="font-family: Courier New, Courier, monospace;">Map</span>, где ключами есть значения <a href="http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html" target="_blank">enum</a>. Не все это знают, но эффективность хранения элементов и скорость работы намного превышает другие реализации, при использовании перечислений для ключей.<br />
<br />
Реализация <a href="http://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">WeakHashMap</span></a> основана на использовании слабых ссылок (<a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%BB%D0%B0%D0%B1%D0%B0%D1%8F_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B0" target="_blank"><span style="font-family: Courier New, Courier, monospace;">WeakReference</span></a>) для ключей. Это позволяет эффективно использовать <span style="font-family: Courier New, Courier, monospace;">Map</span> для временного хранения информации, где запись будет удалятся, когда <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%B1%D0%BE%D1%80%D0%BA%D0%B0_%D0%BC%D1%83%D1%81%D0%BE%D1%80%D0%B0" target="_blank">сборщик мусора</a> в Java удалит объект ключа. Для продуктивного и правильного использования этой реализации необходимо понимание механизма ссылок в Java и работы сборщика мусора. Об этом можно почитать, например, <a href="http://habrahabr.ru/post/169883/" target="_blank">тут</a>.<br />
<br />
<span id="hometask">Небольшое домашнее задание для практики навыков работы с этими реализациями:</span>
<br />
<blockquote class="tr_bq">
Необходимо доработать программу, созданную в результате выполнения <a href="http://yuriytkach.blogspot.com/2013/07/hashset-and-treeset-use.html#hometask" target="_blank">задания из прошлого поста</a>. Немного изменив <a href="http://goo.gl/nOgEg" target="_blank">shell-скрипт</a>, я сделал так, чтобы теперь в файл <a href="http://goo.gl/kz6sl" target="_blank">holidays.txt</a> дописылась информация о том, какой стране принадлежит праздник. Таким образом, каждая строка в этом файле теперь выглядит следующим образом:<br />
<br />
<div style="text-align: center;">
<дата> <название праздника> (<страна праздника>)</div>
<br />
Неоходимо дописать парсинг этого файла, чтобы теперь в объект класса <span style="font-family: Courier New, Courier, monospace;">Holiday</span> также записывалась страна. Но, так как страны повторяются в файле, то необходимо сделать так, чтобы не создавались новые строки в памяти программы, хранящие одинаковые данные. Поясню дополнительно на примере.<br />
<br />
Содержание файла holidays.txt:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">2013/10/26 Всероссийский день гимнастики (Праздники России)<br />2013/6/29 День партизан и подпольщиков (Праздники России)</span></blockquote>
Прочитав этот файл, программа должна создать 2 объекта класса <span style="font-family: Courier New, Courier, monospace;">Holiday</span>. Каждый из них будет хранить ссылки на следующие объекты:<br />
<ul>
<li>разные объекты класса <span style="font-family: Courier New, Courier, monospace;">Date</span></li>
<li>разные объекты класса <span style="font-family: Courier New, Courier, monospace;">String</span>, хранящие название празника</li>
<li>один и тот же объект класса <span style="font-family: Courier New, Courier, monospace;">String</span>, в котором будет записано <span style="font-family: Courier New, Courier, monospace;">"Праздники России"</span>.</li>
</ul>
Кстати, так как в один и тот же день может быть несколько праздников, то можно сделать так, чтобы объект <span style="font-family: Courier New, Courier, monospace;">Date</span> тоже был один для каждого для, в который есть хоть один праздник.<br />
<br />
Для реализации это задания необходимо использовать <span style="font-family: Courier New, Courier, monospace;">WeakHashMap</span>.</blockquote>
Видео, где я рассказываю про реализации интерфейса <span style="font-family: Courier New, Courier, monospace;">Map</span>, их свойства и особенности:<br />
<br />
<center>
<iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/5Iu4ZUcrJ0g?list=PL6jg6AGdCNaWtTjsYJ9t0VaITpIZm4pMt" width="640"></iframe></center>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com0Kiev, Kyiv city, Ukraine50.4501 30.52340000000003849.8023485 29.232506500000039 51.0978515 31.814293500000037tag:blogger.com,1999:blog-6797839624244344630.post-26860003443698385032013-07-16T01:58:00.001+03:002013-07-20T22:59:27.982+03:00Использование HashSet и TreeSet<div class="separator" style="clear: both; text-align: left;">
<span imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk5ZmZORPq2wKfLz239tDgGZBniVQCG_wQNHpfVtvy8ptMCpljUW__qA4i2i8dK-9O7Iw5jrHTZaQwj7y7nFYPfKGtG3HgHpYE31ZMT4W7X7mzqMYri13nqa187wxtzD0e6V2YIa5xzCk/s200/Apples-1.jpg" width="200" /></span><span style="font-family: Courier New, Courier, monospace;"><a href="http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html" target="_blank">HashSet</a></span><span style="font-family: inherit;"> и </span><span style="font-family: Courier New, Courier, monospace;"><a href="http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html" target="_blank">TreeSet</a></span><span style="font-family: inherit;"> - две наиболее распространенные реализации интерфейса </span><span style="font-family: Courier New, Courier, monospace;"><a href="http://docs.oracle.com/javase/7/docs/api/java/util/Set.html" target="_blank">Set</a></span><span style="font-family: inherit;"> в <a href="http://en.wikipedia.org/wiki/Java_collections_framework" target="_blank">Java Collections Framework</a>. Первая основана на использовании функции </span><span style="font-family: Courier New, Courier, monospace;"><a href="http://ru.wikipedia.org/wiki/%D0%A5%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5" target="_blank">hashCode</a></span><span style="font-family: inherit;"> и структуры данных “<a href="http://ru.wikipedia.org/wiki/%D0%A5%D0%B5%D1%88-%D1%82%D0%B0%D0%B1%D0%BB%D0%B8%D1%86%D0%B0" target="_blank">хеш-таблица</a>”, вторая - на основе сравнения элементов и структуры данных “<a href="http://ru.wikipedia.org/wiki/%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE" target="_blank">бинарное дерево</a>” (точнее <a href="http://ru.wikipedia.org/wiki/Red-black_tree" target="_blank">красно-черное дерево</a>). Знание и понимание отличий этих структур данных необходимо для любого программиста. К сожалению, многие лишь поверхностно рассматривают их, что приводит к созданию неэффективного кода, а иногда и к багам. Познакомиться с этими и другими классами коллекций Java можно, посмотрев <a href="http://youtu.be/87pm79sPSvc?t=35m55s" target="_blank">урок 10</a> из курса <a href="http://www.youtube.com/playlist?list=PLB0276A0A62BDEF06" target="_blank">Java для тестировщиков</a>. Для детального изучения необходимо читать <a href="http://algolist.ru/ds/index.php" target="_blank">дополнительную литературу</a>. В данном видео Вы познакомитесь с некоторыми особенностями этих классов, незнание которых может привести к возникновению ошибок или изобретению новых “велосипедов”.</span></div>
<span style="font-family: inherit;"><br />Я думаю, что некоторым из Вас это видео может показаться неинтересным, не открывшим ничего нового. Это хорошо, что Вы знаете эти темы - подождите следующих видео :) А я буду рад за тех, кто почерпнет что-то полезное из этого материала. Потому что на самом деле, реальные баги в реальных проектах, которые мне пришлось отлавливать, возникли как раз из-за невнимательности (или незнания) при работе с этими реализациями </span><span style="font-family: Courier New, Courier, monospace;">Set</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br />Так как многие из Вас хотят домашнего задания, чтобы потренировать навыки программирования, то вот одно, среднего уровня сложности:</span><br />
<blockquote class="tr_bq">
<span style="font-family: inherit;" id="hometask">Написать программу, которая выводит 3 блока информации:</span>
<br />
<ul>
<li><span style="font-family: inherit;">список праздников на сегодняшний день</span></li>
<li><span style="font-family: inherit;">список праздников на завтрашний день</span></li>
<li><span style="font-family: inherit;">список праздников на ближайшие 5 дней, не включая сегодняшний и завтрашний дни</span></li>
</ul>
<span style="font-family: inherit;">Список праздников прочитать при старте программы из этого файла: <a href="http://goo.gl/kz6sl" target="_blank">holidays.txt.zip</a><br />Каждую строку в этом файле преобразовать в объект класса </span><span style="font-family: Courier New, Courier, monospace;">Holiday</span><span style="font-family: inherit;">, который </span><span style="font-family: Courier New, Courier, monospace;">implements Comparable<Date></span><span style="font-family: inherit;">, и который будет иметь два поля: </span><span style="font-family: Courier New, Courier, monospace;">Date date</span><span style="font-family: inherit;"> и </span><span style="font-family: Courier New, Courier, monospace;">String name</span><span style="font-family: inherit;">.<br />Для хранения объектов </span><span style="font-family: Courier New, Courier, monospace;">Holiday</span><span style="font-family: inherit;"> в памяти использовать </span><span style="font-family: Courier New, Courier, monospace;">TreeSet</span><span style="font-family: inherit;">.<br />Результат работы программы должен быть приблизительно таким:</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">#>java package.name.ShowHoliday<br />
Сегодня:<br />Праздник 1<br />Праздник 2<br /><br />
Завтра:<br />
Праздник 3<br />Праздник 4<br /><br />
Скоро:<br />
Ср, 17 июля - Праздник 5<br /> - Праздник 6<br />
Чт, 18 июля - Праздник 7<br /> - Праздник 8</span><br />
<span style="font-family: inherit;"><br />Реализовать в программе возможность передать заданный день и количество дней в командной строке. В этом случае вывести все праздники на этот день и на следующее количество дней, оформив вывод так, как сделано в блоке “Скоро” при обычном запуске программы.</span></blockquote>
<span style="font-family: inherit;"><br />P.S. Если вдруг кому интересно, то для формирования файла с праздниками я написал <a href="http://ru.wikipedia.org/wiki/Shell_script" target="_blank">shell-скрипт</a> на <a href="http://ru.wikipedia.org/wiki/Bash" target="_blank">bash</a>, который посылает запросы на сайт и парсит праздники с результирующей страницы. Вы можете скачать скрипт и поиграться с ним (нужен Linux): <a href="http://goo.gl/nOgEg" target="_blank">holiday_parse.sh</a></span><br />
<span style="font-family: inherit;"><br />Ну и, собственно, видео:</span><br />
<br />
<center>
<iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/-S_huEuNJiU" width="640"></iframe>
</center>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com0Kiev, Kyiv city, Ukraine50.4501 30.52340000000003849.8023485 29.232506500000039 51.0978515 31.814293500000037tag:blogger.com,1999:blog-6797839624244344630.post-19649046200274055952013-06-10T14:38:00.004+03:002013-11-11T16:52:19.318+02:00Курсы Advanced Java<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9uVf58ekAp4_wAzCxJZ77WVnv9crp5wYUfD1u-BYGLy6wqjqjV8EstPfYxmj0zf-l5pBmfjS2TAGIy4wnbaIocdER915rwhjT8b1TGseVqjCKWU7tbF35XQ_kSg87rh2Ch3osco2I6E8/s1600/cats.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9uVf58ekAp4_wAzCxJZ77WVnv9crp5wYUfD1u-BYGLy6wqjqjV8EstPfYxmj0zf-l5pBmfjS2TAGIy4wnbaIocdER915rwhjT8b1TGseVqjCKWU7tbF35XQ_kSg87rh2Ch3osco2I6E8/s200/cats.jpg" width="182" /></a></div>
Опыт общения с различного уровня программистами на языке Java - как на собеседованиях, так и просто в дружественной обстановке - показал наличие некоторых пробелов в знаниях особенностей языка, а также его инструментов. В целом, причины этого вполне объяснимы – ведь, если все время программируешь, например, web-интерфейсы, то не будешь особо задумываться над различными способами взаимодействия с базами данных или обеспечения эффективного чтения/записи файлов. Однако, никогда не знаешь, к чему может привести очередной виток в карьере. Поэтому хорошее владение выбранным языком программирования и знание его особенностей просто необходимо, чтобы не изобретать повторно велосипеды и не ощущать удары грабель по уже набитым шишкам. Выделив отдельные темы из области Java Core, в которых было замечено большего всего пробелов, а также которые, возможно, сложны для понимания из-за отсутствия практики, я создал курс Advanced Java, который и представляю Вашему вниманию.<br />
<br />
Об основах языка Java я уже рассказал в курсе <a href="http://www.youtube.com/playlist?list=PLB0276A0A62BDEF06" target="_blank">Java для тестировщиков</a>. Конечно, были затронуты далеко не все темы и многие из них рассмотрены очень поверхностно. Во-первых, этого было достаточно для слушателей, а во-вторых, я считаю, что заинтересованный программист сможет и сам отыскать необходимую ему информацию, главное - показать направление. В курсе <a href="http://www.youtube.com/playlist?list=PLD964614607573AFD" target="_blank">Java Практика</a> я постарался рассказать, как писать программы, применяя имеющиеся знания, а также дал различные домашние задания для закрепления материала - ведь ничто не запоминается лучше, чем то, что напишешь сам.<br />
<br />
Курс Advanced Java построен в первую очередь на основе практики. Т.е. Вы не только узнаете, как использовать тот или иной инструмент, но также сможете написать код. Такая практика не только поможет лучше понять изложенное в тренингах, но и закрепит Ваши умения, чтобы использовать их на деле. В записях данного блога я постараюсь также написать несколько домашних заданий по отдельным темам, чтобы помочь Вам лучше закрепить материал. На видео я предлагаю решения некоторых поставленных задач, однако советую Вам сначала написать код самостоятельно, ведь на реальной работе Вам редко когда будут в точности говорить, что и как делать.<br />
<br />
Данный курс разбит на пять отдельных мини-курсов, которые охватывают такие темы, как <a href="http://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D1%8C" target="_blank">многопоточность</a> (concurrency), <a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BB%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">коллекции</a> (collections), <a href="http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5" target="_blank">обобщения</a> (generics), <a href="http://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%BD%D0%BE%D1%82%D0%B0%D1%86%D0%B8%D1%8F_(Java)" target="_blank">аннотации</a> (annotations), <a href="http://ru.wikipedia.org/wiki/Reflection" target="_blank">рефлексию</a> (reflection) и <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%80%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F" target="_blank">сериализацию</a> (serialization). Эти мини-курсы можно изучать отдельно, по каждому из них будет выпущено несколько видео. Единственное, что стоит упомянуть – вторая часть мини-курса по коллекциям посвящена <a href="http://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B0%D1%8F_%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F" target="_blank">неблокирующим реализациям коллекций</a> (concurrent collections), и ее стоит изучать после мини-курса по многопоточности.<br />
<br />
Мини-курс "<a href="http://www.youtube.com/playlist?list=PL6jg6AGdCNaXo06LjCBmRao-qJdf38oKp" target="_blank"><b>Advanced Java - Concurrency</b></a>" знакомит со сложными концепциями многопоточности и параллелизма в языке Java на основе пакета java.util.concurrent. В нем кратко вспоминаются основные механизмы <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)" target="_blank">синхронизации</a> в Java, одновременно представляются общие проблемы, связанные с использованием потоков (например, возникновение <a href="http://ru.wikipedia.org/wiki/%D0%92%D0%B7%D0%B0%D0%B8%D0%BC%D0%BD%D0%B0%D1%8F_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0" target="_blank">взаимной блокировки</a> (deadlock)), и показываются эффективные способы их решения. Курс знакомит с высокоуровневыми методами синхронизации с использованием CountDownLatch, CyclicBarrier, ThreadLocal, а также различными Executors для запуска потоков.<br />
<br />
Мини-курс “<b><a href="https://www.youtube.com/playlist?list=PL6jg6AGdCNaWtTjsYJ9t0VaITpIZm4pMt" target="_blank">Advanced Java – Collections</a></b>” посвящен детальному рассмотрению стандартных реализаций интерфейсов <a href="http://en.wikipedia.org/wiki/Java_collections_framework" target="_blank">Java Collections Framework</a> (hash maps, queues, sets), объясняет их особенности, способы применения и знакомит с некоторыми интересными свойствами, позволяющими повысить эффективность работы с коллекциями в программе, а также избежать возникновения скрытых багов. Вторая часть данного мини-курса знакомит с неблокирующими реализациями коллекций (non-blocking lists and sets, concurrent maps, blocking queues), объясняет разницу между ними, а также на практике показывает их плюсы и минусы, и возможное применение.<br />
<br />
Мини-курс “<b><a href="https://www.youtube.com/playlist?list=PL6jg6AGdCNaX1yIJpX4sgALBTmTVc_uOJ" target="_blank">Advanced Java – Generics</a></b>” подробно рассматривает скрытые проблемы, возникающие при игнорировании женериков, объясняет особенности наследования при использовании классов с обобщенной типизацией, а также показывает, как повысить эффективность кода с применением метасимволов (<a href="http://en.wikipedia.org/wiki/Wildcard_(Java)" target="_blank">wildcard</a>) и расширителей обобщения (extends и super).<br />
<br />
<span imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="164" src="http://upload.wikimedia.org/wikipedia/commons/2/26/Java.png" width="200" /></span>Мини-курс “<b><a href="https://www.youtube.com/playlist?list=PL6jg6AGdCNaWgDwiPjmlIvkr8s2OdDH2P" target="_blank">Advanced Java – Annotations/Reflection</a></b>” рассказывает о том, как создавать собственные аннотации, определять их свойства и обрабатывать их с помощью рефлексии (reflection). В дополнении к этому данный мини-курс знакомит с другими часто используемыми особенностями применения Java Reflection API.<br />
<br />
Мини-курс “<b><a href="http://www.youtube.com/playlist?list=PL6jg6AGdCNaXYzZwvvZ-3NRTr63XeYazS" target="_blank">Advanced Java – Serialization</a></b>” представляет различные популярные техники для сериализации объектов в Java. Рассматривается базовая сериализация с применением встроенных инструментов, объясняются тонкости ее настройки и использования. Кроме того, мини-курс знакомит со ставшей уже встроенной сериализацией в XML с применением <a href="http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding" target="_blank">JAXB</a>, а также с сериализацей в формат <a href="http://ru.wikipedia.org/wiki/JSON" target="_blank">JSON</a> с помощью библиотеки от <a href="http://code.google.com/p/google-gson/" target="_blank">Google</a>.Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com0Kiev, Kyiv city, Ukraine50.4501 30.52340000000003849.8023485 29.232506500000039 51.0978515 31.814293500000037tag:blogger.com,1999:blog-6797839624244344630.post-62086931405435527442012-11-05T17:25:00.001+02:002012-11-05T17:26:25.445+02:00Java Практика - Занятие 9<div class="separator" style="clear: both; text-align: center;">
<a href="http://ant.apache.org/" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="123" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgcQTyJt4T9q94mNFF1KHHgkZzqjS7bQzkcY3ruRb6Nn3ycbUXTACbOCgExinx9IUcCcx8QipMBwpuUCfABm9Pl3l06R_gQAXTptaleAlvXgebQoW6U95MRexeVcZzhjYud2pqZwXPOpY/s200/Apache_Ant.png" width="200" /></a></div>
На девятом занятии мы практиковались собирать проект с помощью <a href="http://ant.apache.org/" target="_blank">Apache Ant</a>. Про <a href="https://ru.wikipedia.org/wiki/Apache_Ant" target="_blank">Ant</a> и про <a href="https://ru.wikipedia.org/wiki/Apache_Maven" target="_blank">Maven</a> я рассказывал на последнем <a href="https://www.youtube.com/watch?v=ouUuT2uEuiU&list=SPB0276A0A62BDEF06&index=19&feature=plpp_video" target="_blank">19 уроке</a> из курса <a href="https://www.youtube.com/playlist?list=PLB0276A0A62BDEF06&feature=view_all" target="_blank">Java для Тестировщиков</a>. В этот раз мы более подробно остановились на создании скрипта сборки, написали скрипт "с нуля" для очень простого Java проекта и рассмотрели основные цели Ant. Чтобы не объяснять все это "на пальцах" и не писать много текста на доске, я воспользовался <a href="http://www.eclipse.org/" target="_blank">Eclipse</a>, где сразу в IDE и показывал, как что делать.<br />
<br />
Ответ на вопрос, почему именно Ant, а не Maven, достаточно прост: Ant часто используется в проектах в нашей компании и поэтому оказался востребованным для слушателей курса. Объяснять, <a href="http://stackoverflow.com/questions/603189/differences-between-ant-and-maven" target="_blank">что лучше</a>, а что хуже, я не здесь не буду - решите каждый сам для себя, попробовав оба инструмента. Урок по использованию Maven мы, возможно, сделаем, однако пока в планах такого нету.<br />
<br />
Скачать исходные файла примера, который был создан на видео, можно по <a href="http://goo.gl/mqW2m" target="_blank">этой ссылке</a>.<br />
<br />
Ну и, собственно, видео:<br />
<br />
<br />
<div align="center">
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="360" src="http://www.youtube.com/embed/PCfQLAeP0Q4" width="640"></iframe>
</div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com6tag:blogger.com,1999:blog-6797839624244344630.post-28410863887830449802012-10-18T19:12:00.001+03:002012-10-18T19:12:44.632+03:00Java Практика - Занятие 8<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/6/68/XML.svg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://upload.wikimedia.org/wikipedia/commons/6/68/XML.svg" width="175" /></a></div>
На восьмом занятии мы рассмотрели работу с XML файлами в Java. Про то, <a href="http://ru.wikipedia.org/wiki/XML" target="_blank">что такое XML</a>, я не рассказывал в курсе <a href="https://www.youtube.com/playlist?list=PLB0276A0A62BDEF06&feature=plcp" target="_blank">Java для тестировщиков</a> и на этом занятии тоже не останавливался — подразумевается, что Вы это уже знаете. Мы рассмотрели три базовых способа взаимодействия со структурными файлами XML: чтение и поиск с помощью SAX, чтение и создание с помощью DOM, и маршалинг и демаршалинг с помощью JAXB. Мы рассматривали работу с очень простыми XML документами без <a href="http://ru.wikipedia.org/wiki/XSD" target="_blank">схем</a> или <a href="http://ru.wikipedia.org/wiki/DTD" target="_blank">DTD</a> описаний.<br />
<br />
<a href="http://ru.wikipedia.org/wiki/SAX" target="_blank">SAX</a>-парсер — это самый простой способ чтения XML документа и поиска информации в нём. Однако, в силу своей простоты, обработка чуть более сложных документов (с множеством уровней иерархии элементов) становится очень трудоёмкой задачей. На практике применяется, скорее, для очень простых, либо очень больших по объёму документов. SAX-парсер встроен в саму Java, и никаких дополнительных библиотек для его использования не нужно. На <a href="http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/" target="_blank">этом ресурсе</a> (англ.) есть простой пример по чтению документа этим парсером. Также, там внизу <a href="http://www.mkyong.com/java/how-to-read-utf-8-xml-file-in-java-sax-parser/" target="_blank">ссылка</a> на то, как читать UTF-8 XML документ c помощью SAX.
<br />
<br />
Другой способ чтения XML документов — это использование объектной модели документа <a href="http://ru.wikipedia.org/wiki/Document_Object_Model" target="_blank">DOM</a>. Данный способ позволяет также легко модифицировать и создавать документ. Так как структура XML файлов представлена в виде иерархии, то ее легко отобразить с помощью объектов в Java, где можно выделить родителя (<a href="http://docs.oracle.com/javase/6/docs/api/org/w3c/dom/Document.html" target="_blank">Document</a>) со списком потомков (<a href="http://docs.oracle.com/javase/6/docs/api/org/w3c/dom/Element.html" target="_blank">Element</a>), у которых могут быть свои потомки и т.д. DOM — это программный интерфейс, и существует различные его реализации. В самой Java есть классическая реализация, но большей популярностью пользуется библиотека <a href="http://ru.wikipedia.org/wiki/JDOM" target="_blank">JDOM</a>. Попросту говоря, в ней больше полезных функций, и поэтому работать с ней легче. Собственно, на видео я приводил примеры функций как раз этой библиотеки. На том же англ. ресурсе есть простые и хорошие примеры как <a href="http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/" target="_blank">читать XML</a> с помощью DOM и как <a href="http://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/" target="_blank">создавать документ</a>. Также там есть пример, как <a href="http://www.mkyong.com/java/how-to-read-xml-file-in-java-jdom-example/" target="_blank">читать документ</a> с помощью JDOM и <a href="http://www.mkyong.com/java/how-to-create-xml-file-in-java-jdom-parser/" target="_blank">создавать</a> его.
<br />
<br />
Еще одним способом работы с XML документами, который уже можно отнести к классическим — это использование <a href="http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding" target="_blank">JAXB</a>: <a href="https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5" target="_blank">отображения</a> XML в Java классы. Раньше, эта технология была доступна при подключении дополнительной библиотеки, но сейчас она уже включена в ядро Java. Суть отображения можно вкратце описать так: приложение, которое обрабатывает информацию, представляет данные в виде иерархии и взаимосвязи различных объектов; определенные поля в этих объектах (которые описаны в соответствующих классах) помечаются мета-информацией (в нашем случае, <a href="http://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%BD%D0%BE%D1%82%D0%B0%D1%86%D0%B8%D1%8F_(Java)" target="_blank">аннотациями</a>), которая используется JAXB для сохранения значений полей в XML документ, а также для чтения их из документа. Процесс сохранения данных называется <a href="https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%80%D1%88%D0%B0%D0%BB%D0%B8%D0%BD%D0%B3" target="_blank">маршалингом</a>. Процесс чтения — демаршалингом. Использовать JAXB очень удобно, если цель Вашего приложения — это не работа с XML, а работа с информацией. А так как информацию надо где-то хранить и где-то брать, и если это «где-то» - это XML-файл, то процесс ввода/вывода можно сделать достаточно прозрачным и легко модифицируемым. И снова, тот же англ. ресурс содержит <a href="http://www.mkyong.com/java/jaxb-hello-world-example/" target="_blank">пример работы с JAXB</a>.
<br />
<br />
Так как XML — это достаточно взрослый формат представления данных, то очень много написано документации по работе с ним на любом языке.
<br />
<br />
В качестве домашнего задания для данного урока, можно выполнить следующее:<br />
<br />
<ol>
<li>Создать XML документ.</li>
<li>Найти какую-либо информацию в документе с помощью SAX-парсера.</li>
<li>Прочитать весь документ с помощью DOM-парсера (или JDOM) и вывести его на экран. </li>
<li>Создать несколько взаимосвязанных классов с несколькими полями и отобразить их с помощью JAXB: сохранить XML документ и прочитать его. Для тех, кто выполнял задания из нескольких первых занятий, то можно добавить аннотации к классам Product и сохранить информацию о продуктах в XML.</li>
</ol>
Ну и, собственно, видео занятия:<br />
<br />
<div align="center">
<iframe allowfullscreen="true" frameborder="0" height="360" src="http://www.youtube.com/embed/nyyD_Zpk6dI" width="640"></iframe>
</div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com2tag:blogger.com,1999:blog-6797839624244344630.post-49869418329059656932012-09-10T16:32:00.000+03:002012-09-10T16:32:43.927+03:00Java Практика - Занятие 7<div class="separator" style="clear: both; text-align: center;">
<span imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVvjK8lT7GKicUE7nA027Ak0ODkszd2otRWgRWTBcA5U151v_MzrhBGUC6yexP665f9RXer2cjSJOPB6kstVQ0seTclRaoBGeIKVyLUclXG9dr9OyqBcUXm-FY22mb2l0ujKciUhZJdK4/s200/image.png" width="200" /></span></div>
Седьмое занятие мы посвятили работе с <a href="https://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB" target="_blank">файлами</a> в Java. Мы рассмотрели базовые операции, такие как создание, удаление, и получение доступа к файлам и каталогам. Немного остановились на <a href="https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%82%D0%BE%D0%BA_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85" target="_blank">потоках</a>, как бинарных, так и <a href="http://docs.oracle.com/javase/tutorial/essential/io/charstreams.html" target="_blank">символьных</a>, и их использовании для чтения и записи файлов. В конце занятия, я рассказал про библиотеку <a href="https://commons.apache.org/io/" target="_blank">Apache Commons IO</a>, в которой реализованы полезные методы для работы с файлами и потоками ввода/вывода. И, конечно, домашнее задание для закрепления материала. Про работу с файлами и потоками я рассказывал на <a href="https://www.youtube.com/watch?v=_4WN6UKUUBU&list=SPB0276A0A62BDEF06&index=11&feature=plpp_video" target="_blank">уроке 11</a> из курса Java для тестировщиков, так что начинать изучение темы следует оттуда.<br />
<br />
Для доступа к файлам в Java используются классы из пакета <a href="http://docs.oracle.com/javase/6/docs/api/java/io/package-summary.html" target="_blank">java.io</a>. Для реализации высокопроизводительных операций ввода/вывода существуют также классы из пакета <a href="https://ru.wikipedia.org/wiki/New_I/O" target="_blank">java.nio</a>. Однако, их рассмотрение выходит за рамки данного курса. К тому же, я считаю, что разобраться там не составит труда после освоения традиционных способов.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="109" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7dmJpWK8DNaYiuQiTZB2IOOB-SMHKMZdE-nFEOQJFUb9wf8YP52AlVPKqVanhiMriKcJE9tQEveSUQ5VfKbqfK2CtokNOSwO4L658oTVWs7wR1yz290UD9a8giOIYcr3X2rk1SJcGvEk/s320/io-ins.gif" width="320" /></span></div>
Работу с файлами можно условно разделить на две составляющие. Во-первых, это операции, связанные с доступом и местоположением файлов и каталогов, такие как создание, перемещение, удаление, получение списка (у директории). Во-вторых, это операции чтения и записи содержимого файлов. Для первого случая используется базовый класс <a href="http://docs.oracle.com/javase/6/docs/api/java/io/File.html" target="_blank">java.io.File</a>, а также другие системные классы. Во втором случае используются потоки ввода/вывода. Стандартных системных классов Java часто бывает недостаточно для выполнения необходимых операций с файлами (например, <a href="http://stackoverflow.com/questions/106770/standard-concise-way-to-copy-a-file-in-java" target="_blank">копирование файла</a>), и в таком случае использование сторонних библиотек выручает разработчика, чтобы не "изобретать велосипед" заново. Для работы с потоками в Java есть все, что нужно, хоть часто и приходится писать много сопутствующего кода для корректной обработки всех ситуаций. В данном случае также помогают сторонние библиотеки, предоставляющие методы, которые либо полностью выполняют нужные действия, либо избавляют от необходимости писать блоки стандартных вызовов.<br />
<br />
Все операции ввода/вывода, а также методы создания потоков в Java выбрасывают <a href="https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B9#.D0.9F.D1.80.D0.BE.D0.B2.D0.B5.D1.80.D1.8F.D0.B5.D0.BC.D1.8B.D0.B5_.D0.B8.D1.81.D0.BA.D0.BB.D1.8E.D1.87.D0.B5.D0.BD.D0.B8.D1.8F" target="_blank">проверяемые исключения</a>. В обязательном порядке их необходимо отлавливать и обрабатывать. Как именно — это зависит уже от приложения, можно просто завершить работу, а можно попытаться восстановить нормальное функционирование с уведомлением пользователя. В любом случае, программист должен решить, что будет делать программа в случае возникновения ошибок ввода/вывода. Для ознакомления с исключениями можно послушать мой <a href="https://www.youtube.com/watch?v=RcwyUIyF7kI&list=SPB0276A0A62BDEF06&index=9&feature=plpp_video" target="_blank">урок 9</a> из курса Java для тестировщиков.<br />
<br />
На следующем занятии мы рассмотрим работу с двумя распространёнными типами файлов — properties и XML.<br />
<br />
Домашнее задание для этого занятия:<br />
<br />
<ol>
<li>Написать программу, которая читает текстовый файл, состоящий из нескольких строк, и записывает эти строки в отсортированном по длине порядке в другой текстовый файл. <br /><br />Например, файл <span style="font-family: "Courier New",Courier,monospace;">aa.txt</span>, содержит следующие строки:
<br /><blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;">World!<br />Hello<br />And how do you do?</span></blockquote>
Созданный файл <span style="font-family: "Courier New",Courier,monospace;">bb.txt</span> будет содержать эти же строки в отсортированном по длине виде:
<br /><blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;">Hello<br />
World!<br />
And how do you do?</span></blockquote>
Для небольшого усложнения этого задания можно сделать следующее:
<br /><ul>
<li>добавить возможность указывать исходный файл, целевой файл и направление сортировки (восходящая или спадающая) в командной строке, например так:<br /><blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;">java SortFile aa.txt bb.txt asc</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span></blockquote>
, где <span style="font-family: "Courier New",Courier,monospace;">SortFile</span> — класс, который мы запускаем, <span style="font-family: "Courier New",Courier,monospace;">aa.txt</span> — исходный файл, <span style="font-family: "Courier New",Courier,monospace;">bb.txt</span> — целевой файл, <span style="font-family: "Courier New",Courier,monospace;">asc</span> или <span style="font-family: "Courier New",Courier,monospace;">desc</span> — направление сортировки. </li>
</ul>
<br />
</li>
<li>Написать программу, которая копирует все файлы из заданного каталога в целевой, при этом переименовывая их в случайном порядке, назначая имена файлам из числовой последовательности от 1 до N, где N — это количество файлов в каталоге. При этом имена файлов не могут повторяться. <br /><br />Например, есть каталог, в котором хранятся файлы:
<span style="font-family: 'Courier New', Courier, monospace;">a.txt
b.txt
c.txt
</span>Программа копирует эти файлы в другой каталог, назначая им следующие имена:
<span style="font-family: 'Courier New', Courier, monospace;">1.txt
2.txt
3.txt</span>
При этом назначение имен происходит случайным образом, т. е. например, <span style="font-family: 'Courier New', Courier, monospace;">a.txt → 2.txt</span>,<span style="font-family: 'Courier New', Courier, monospace;"> b.txt → 1.txt</span>, <span style="font-family: 'Courier New', Courier, monospace;">c.txt → 3.txt</span>. Для выбора случайного числа, можно использовать Java класс <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Random.html" target="_blank">Random</a>.</li>
</ol>
Ну и, собственно, видео. Прошу прощения за качество видео - в последний момент сломался мой фотоаппарат и пришлось записывать на телефоны - сначала на один (пока там место не закончилось), потом на второй. Стол, на котором были установлены телефоны, шатался, поэтому видео я обработал <a href="http://habrahabr.ru/post/116002/" target="_blank">стабилизатором от youtube</a>.<br />
<div align="center">
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="360" src="http://www.youtube.com/embed/2gddu47wooE" width="640"></iframe>
</div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com5tag:blogger.com,1999:blog-6797839624244344630.post-42971104203629378242012-09-09T15:23:00.001+03:002012-09-09T15:25:00.927+03:00Java Практика - Занятие 6<div class="separator" style="clear: both; text-align: center;">
<span imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBt8ZQTi9mO7VrHXrnNcrsOzkOYpceW8301o6Y1Z_M3le5xg7VHKwGJQVW3OGPtEC9Zn2o16AbIM1gXQgUQhe5oFYzpBUPs__FJoPKvfWI12REyD7s1wuSwX5Wbun4BpCYBtEzJQabPpg/s320/%D0%9E%D0%9E%D0%9F-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BB%D1%8E%D0%B1%D0%BE%D0%B2%D1%8C-%D0%BF%D0%BE%D1%86%D0%B5%D0%BB%D1%83%D0%B9-150407.jpeg" width="320" /></span></div>
После длительного перерыва, вызванного жарким летом и моим двойным отпуском, мы наконец-то вернулись к занятиям. Так как многие слушатели тоже были в отпуске, и кто-то что-то подзабыл, мы решили немного восстановить знания, обобщить известную информацию и уточнить план дальнейших действий. По просьбе "трудящихся" мы еще раз более подробно остановились на использовании <a href="https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81_(%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">интерфейсов</a> в Java. Я уже рассказывал про это на <a href="https://www.youtube.com/watch?v=ZtwG6gcaWxE&feature=bf_next&list=SPB0276A0A62BDEF06" target="_blank">уроке 5</a> из курса Java для тестировщиков. Можно рассматривать данное занятие, как дополнительную информацию, либо как подачу информации другими словами. Занятие получилось скорее теоретическим, чем практическим. Домашнего задания по определенным причинам нету :)
<br />
<br />
<div align="center">
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="http://www.youtube.com/embed/Q4GlrFK5qcg" width="560"></iframe>
</div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com0tag:blogger.com,1999:blog-6797839624244344630.post-20177175725592941992012-07-12T14:58:00.001+03:002012-07-12T19:35:32.233+03:00Java Практика - Занятие 5<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_mT6h6B7Xif15x3WcVHYXaXP9AzEcS9K4Gt9hVJEjHtkzkfMrpll9cHV0Op7K2MrwoQWv8gJtOMc0kRrjDV2EcGuu5mR-nG8o_QnK9tUTge_9p6NJ71fQnXIA1fVP7YhTWy83pJiYBT4/s1600/Computer-Bridge.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_mT6h6B7Xif15x3WcVHYXaXP9AzEcS9K4Gt9hVJEjHtkzkfMrpll9cHV0Op7K2MrwoQWv8gJtOMc0kRrjDV2EcGuu5mR-nG8o_QnK9tUTge_9p6NJ71fQnXIA1fVP7YhTWy83pJiYBT4/s200/Computer-Bridge.jpg" width="200" /></a></div>
На пятом занятии я решил остановиться на использовании <a href="https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BB%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">коллекций</a>, как альтернативу применению массивов для хранения наборов данных. Интерфейсы <a href="https://appliedjava.wordpress.com/2010/09/23/java-collections-framework/" target="_blank">коллекций в Java</a> обеспечивают весь необходимый инструментарий для работы с различными наборами данных, поэтому их употребление, во-первых, повышает скорость разработки программ, а во-вторых, улучшает качество кода за счет повторного использования уже написанного и отлаженного кода. Про коллекции я рассказывал на <a href="https://www.youtube.com/watch?v=87pm79sPSvc" target="_blank">уроке 10</a> в курсе <a href="https://www.youtube.com/playlist?list=PLB0276A0A62BDEF06&feature=plcp" target="_blank">Java для тестировщиков</a>. Так как <a href="http://docs.oracle.com/javase/tutorial/collections/index.html" target="_blank">применение коллекций</a> упрощает разбираемый пример, я немного усложнил логику приложения, чтобы сделать ее более интересной. В дополнению к работе над разбираемой задачей в конце занятия было поставлено одна интересная задача для самостоятельной работы.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBGrN-EGNDryQgqsmYlqK0wL2j_ysCqXxNeF4Tnbrwxp6p517_56BgDel_w0xCWj7x3Y9VATrxHbXwDfETEkEbtqj5ytuiX1TMMEGlbVDhodpg1cG1Sg3GXo0hqrTysUO0zuKLAylVsBQ/s1600/u00220020501gcn01_01.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"><img border="0" height="134" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBGrN-EGNDryQgqsmYlqK0wL2j_ysCqXxNeF4Tnbrwxp6p517_56BgDel_w0xCWj7x3Y9VATrxHbXwDfETEkEbtqj5ytuiX1TMMEGlbVDhodpg1cG1Sg3GXo0hqrTysUO0zuKLAylVsBQ/s200/u00220020501gcn01_01.gif" width="200" /></a></div>
На этом занятии мы рассмотрели не все интерфейсы коллекций и возможные варианты их использования. Это еще предстоит в будущем. Пока что мы остановились только на интерфейсах Collection, List, Map. Также рассмотрели использование <a href="https://ru.wikipedia.org/wiki/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">итератора</a> для прохождения коллекции и возможного удаления элементов.<br />
<br />
Домашнее задание для этого занятия:<br />
<ol>
<li><span style="background-color: white;">Добавить Map продуктов в класс Deal </span></li>
<li><span style="background-color: white;">Изменить методы getCost() и getSum(), чтобы они работали, используя Map продуктов. </span></li>
<li><span style="background-color: white;">Добавить Map свойств в Party вместо массивов keys и value. </span></li>
<li><span style="background-color: white;">Исправить методы ввода/вывода для работы с Map </span></li>
<li><span style="background-color: white;">Добавить возможность выбирать ранее введенный продукт при добавлении его в сделку.</span></li>
</ol>
<span style="background-color: white;">Дополнительная задача для развития навыков программирования:</span><br />
<blockquote class="tr_bq">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnLdcPozeoYKSzjV49U-wxqNeHtGW2jGUZ6ttCI10G9rNHzy31mzaebM0MyVHQmqzUDw4ooCFa6LHMnHdDx0dwDa3aW8ukHJAvnWcCM5dLdeYC8C2Vy5lWjGUQwf23D1UEhFv3AHkxOfI/s1600/tokenz-nautic013.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnLdcPozeoYKSzjV49U-wxqNeHtGW2jGUZ6ttCI10G9rNHzy31mzaebM0MyVHQmqzUDw4ooCFa6LHMnHdDx0dwDa3aW8ukHJAvnWcCM5dLdeYC8C2Vy5lWjGUQwf23D1UEhFv3AHkxOfI/s200/tokenz-nautic013.jpg" width="200" /></a></div>
Написать программу, которая заполняет <a href="https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D1%80%D0%B8%D1%86%D0%B0_(%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)" target="_blank">матрицу</a> (двумерный массив) нулями и единицами так, чтобы получился рисунок песочных часов. Матрица обязательно квадратная. Размер матрицы пользователь вводит с консоли.<br />
Например, для матрицы, размером 5х5, должен получиться такой рисунок:<br />
<span style="font-family: 'Courier New', Courier, monospace;">1 1 1 1 1<br />0 1 1 1 0<br />0 0 1 0 0<br />0 1 1 1 0<br />1 1 1 1 1</span></blockquote>
<span style="background-color: white;">Я также написал возможное решение этой задачи, если вдруг кому-то будет очень сложно. Скачать исходные файлы можно тут: <a href="http://goo.gl/ftKQ2" target="_blank">JavaPractice05.zip</a> (5,9 KB)</span><br />
<br />
Чтобы откомпилировать и запустить этот пример, выполните следующие команды:<br />
<blockquote class="tr_bq">
<span style="font-family: 'Courier New', Courier, monospace;">cd <каталог_куда_распаковали_архив></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">cd src</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">javac *.java</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">java Program5</span> - <i>это для запуска программы о сделках</i><br />
<span style="font-family: 'Courier New', Courier, monospace;">java Program5Additional</span> - <i>это для запуска песочных часов </i></blockquote>
<span style="background-color: white;">Также, если Вы уже умеете работать со средой разработки <a href="http://www.eclipse.org/" target="_blank">Eclipse</a>, то можете <a href="https://www.youtube.com/watch?v=XPDEXGvlYEU" target="_blank">импортировать</a> этот проект в нее и запустить. </span><br />
<span style="background-color: white;"><br /></span><br />
Ну и, собственно, видео занятия:<br />
<br />
<div align="center">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/7gws2decf2g" width="560"></iframe>
</div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com10tag:blogger.com,1999:blog-6797839624244344630.post-72153847382733918272012-07-04T18:11:00.002+03:002012-07-05T13:50:56.253+03:00Java Практика - Занятие 4<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO7NFeSuNM86lW7_PO25UTRJtzDSLPBeJBPFI4SMoaBVfl6i92dlWm6ZKXOvOHZH0OxinRqcOlWAfFLPAudAjjkEKiV8oCkCSwsDUEGLvdNoDPC7oEtAjcm9zFvlkMU3vCBhyphenhyphenRBVeTkow/s1600/concepts-bikeHierarchy.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO7NFeSuNM86lW7_PO25UTRJtzDSLPBeJBPFI4SMoaBVfl6i92dlWm6ZKXOvOHZH0OxinRqcOlWAfFLPAudAjjkEKiV8oCkCSwsDUEGLvdNoDPC7oEtAjcm9zFvlkMU3vCBhyphenhyphenRBVeTkow/s200/concepts-bikeHierarchy.gif" width="200" /></a></div>
На четвертом занятии мы продолжили разбирать пример из <a href="http://yuriytkach.blogspot.com/2012/07/java-practice-lesson-3.html" target="_blank">предыдущего урока</a>, немного усложнив его. Основное внимание в этот раз было уделено <a href="https://ru.wikipedia.org/wiki/%D0%9D%D0%B0%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">наследованию</a>: класс <span style="font-family: 'Courier New', Courier, monospace;">Product</span> мы сделали <a href="https://ru.wikipedia.org/wiki/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%81" target="_blank">абстрактным</a> и создали два его потомка. Также я показал, как можно использовать <a href="https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%B0" target="_blank">переопределение метода</a> для уточнения логики в классе <span style="font-family: 'Courier New', Courier, monospace;">FotoProduct</span>. Также немного поговорили об использовании <a href="https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B0_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">констант</a> в Java.<br />
<br />
Домашним заданием к этому занятию будет сделать все то, о чем мы говорили, а именно:<br />
<br />
<ul>
<li>Написать классы <span style="font-family: 'Courier New', Courier, monospace;">FotoProduct</span> и <span style="font-family: 'Courier New', Courier, monospace;">BotinkiProduct</span></li>
<li>Написать методы для расчета скидки</li>
<li>Написать метод для расчета стоимости продукта с учетом скидки</li>
<li>Добавить поля в классы <span style="font-family: 'Courier New', Courier, monospace;">Product</span> и <span style="font-family: 'Courier New', Courier, monospace;">Party</span></li>
</ul>
<div>
Также, заданием является сделать программу рабочей после вышеуказанных изменений, а именно:</div>
<div>
<ul>
<li>Добавить ввод отдельных продуктов</li>
<li>Добавить ввод информации о <span style="font-family: 'Courier New', Courier, monospace;">Party</span></li>
<li>Добавить вывод информации о <span style="font-family: 'Courier New', Courier, monospace;">Party</span></li>
</ul>
<div>
В качестве дополнительного задания можно сделать следующее:</div>
</div>
<div>
<ul>
<li>Добавить вывод полей отдельных продуктов</li>
<li>Усовершенствовать ввод и вывод, чтобы был более приятным для глаз :)</li>
</ul>
</div>
<b>Обновление:</b> Я в очередной раз написал возможное решение этой задачи. Скачать исходные файлы можно тут: <a href="http://goo.gl/p0p5J">JavaPractice04.zip</a> (4,8 KB). Запуск программы описан в <a href="http://yuriytkach.blogspot.com/2012/07/java-practice-lesson-3.html">предыдущем посте</a>.<br />
<br />
<span style="background-color: white;">Ну и собственно видео:</span><br />
<span style="background-color: white;"><br /></span>
<br />
<div align="center">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/sCTjjkA70ec" width="560"></iframe>
</div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com4tag:blogger.com,1999:blog-6797839624244344630.post-8371526086183162562012-07-01T02:00:00.001+03:002013-11-06T18:00:49.549+02:00Java Практика - Занятие 3<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<span style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj87aiP9e8rt0kZ_WARchMX8hcipYncY70nkt1EWI4ZLNBZCLRiDPF9Mtzhe_HPq7eKxjC3ubb1yBlHMD2ALilqpabWD6jmwCcnC0KHrx6sywCccaTJrpkAQrNPm6nzy7JCamFALIOGPXs/s200/object.gif" width="143" /></span></div>
На третьем занятии мы уже подошли к <a href="https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5" target="_blank">объектам и проектированию</a>. Я рассмотрел создание программы с позиции объектно-ориентированного дизайна. Бегло прошелся по теме <a href="https://www.youtube.com/watch?v=lGQxeGiqmKU" target="_blank">третьего урока</a> из курса <a href="https://www.youtube.com/playlist?list=PLB0276A0A62BDEF06&feature=plcp" target="_blank">Java для тестировщиков</a>, чтобы вспомнить, что такое <a href="https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29" target="_blank">объект</a> и как с ним работать. Далее мы решали задачу, немного похожую на реальный пример: выделяли объекты, рисовали диаграммы и реализовывали методы.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7MwdW14-geRmvJGZHseD5CJH1mCjkw_vxW_w0Syx962xKHxHmkN7Mwk9b1EWwRYAAqMXsOA_WJW_EJZ1z92SPQnAjnSrfG2mJUKq4-wZ_Qa0gO_xV-RLNA0XCFgh6UC3HOWoyBO9aU64/s1600/6a0120a85dcdae970b012877701400970c.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7MwdW14-geRmvJGZHseD5CJH1mCjkw_vxW_w0Syx962xKHxHmkN7Mwk9b1EWwRYAAqMXsOA_WJW_EJZ1z92SPQnAjnSrfG2mJUKq4-wZ_Qa0gO_xV-RLNA0XCFgh6UC3HOWoyBO9aU64/s200/6a0120a85dcdae970b012877701400970c.png" width="122" /></a></div>
На этом занятии я также впервые упомянул про одну из очень полезных книг, а именно книгу по <a href="https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" target="_blank">шаблонам проектирования</a>: <a href="https://ru.wikipedia.org/wiki/Design_Patterns" target="_blank"><b>Приемы объектно-ориентированного проектирования. Паттерны проектирования</b></a> ("Банда четырёх": Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидс). Я считаю, что каждый программист просто обязан изучить эту книгу и по возможности использовать шаблоны в своих программах. Конечно, это не легко будет делать сразу - понимание, где и какой шаблон лучше применять, приходит с опытом. Также, не расстраивайтесь, если Вы сразу не поймете эту книгу. Продолжайте изучать программирование и больше практикуйтесь писать программы - со временем Вы поймете, насколько мощный инструмент у Вас в руках. Однако, есть <a href="http://www.codinghorror.com/blog/2007/07/rethinking-design-patterns.html" target="_blank">небольшое предостережение</a> по поводу шаблонов проектирования: ф<span style="background-color: white;">окусируйтесь на простых решениях проблем, прежде чем сразу браться за применение сложных "рецептов" шаблонов. Так что не забывайте: Keep It Simple :)</span><br />
<br />
<div id="task">Задачу, которую мы решали на занятии следующая:</div>
<blockquote class="tr_bq">
<i>Необходимо реализовать программу, которая будет позволять вводить сделки купли-продажи товаров между двумя участниками. В каждой сделке может быть несколько товаров, сумма сделки рассчитывается из суммы всех товаров. Сумма каждого товара рассчитывается из его стоимости и количества. Программа должна позволить ввести информацию о сделках, сохранить ее в памяти и вывести на экран. Ввод информацию осуществляется с экрана (консоли). Количество дополнительной информацию о сделке, участнике, товаре придумать самому (больше одного поля для класса). </i></blockquote>
<span style="background-color: white;">Форматы данных для хранения информации, которые я предложил, конечно же, не самые оптимальные. Например, использование массивов вместо коллекций, а также использование double для представления денег. Но это не главное для данного примера. Также, вводить информацию с консоли - это долго и нудно, но это тоже не главное. Я не хотел углубляться в способы представления определенной информации, в способы работы с файлами или базой данных - это все темы следующих занятий. <b>Цель этого занятия</b> - это научится выделять объекты, строить между ними связи и попрактиковаться программировать несложную логику. Поэтому ввод с консоли тут идеально подходит, ведь надо будет подумать, как последовательно все ввести, да еще чтобы это было красиво :)</span><br />
<br />
<span style="background-color: white;">На видео я вспоминаю про метод <span style="font-family: 'Courier New',Courier,monospace;">keyboard</span>, который позволяет вводить данные с консоли, и который я обещал выслать слушателям. Итак, вот он: </span><br />
<blockquote class="tr_bq">
<span style="background-color: white;"><span style="font-family: 'Courier New',Courier,monospace;"><span style="color: #351c75;">private</span> String keyboard(String message) {</span></span>
<br />
<span style="background-color: white;"><span style="font-family: 'Courier New',Courier,monospace;">System.<span style="color: #351c75;">out</span>.print(message + <span style="color: #351c75;">": "</span>);</span></span>
<br />
<span style="background-color: white;"><span style="font-family: 'Courier New',Courier,monospace;">Scanner scan = <span style="color: #351c75;">new</span> Scanner(System.in);</span></span>
<br />
<span style="font-family: 'Courier New',Courier,monospace;"><span style="background-color: white;"></span><span style="background-color: white; color: #351c75;">String</span><span style="background-color: white;"> rez = scan.next();</span></span>
<br />
<span style="font-family: 'Courier New',Courier,monospace;"><span style="background-color: white;"></span><span style="background-color: white;">scan.close();</span></span>
<br />
<span style="font-family: 'Courier New',Courier,monospace;"><span style="background-color: white;"></span><span style="background-color: white; color: #351c75;">return</span><span style="background-color: white;"> rez;</span></span>
<br />
<span style="background-color: white;"><span style="font-family: 'Courier New',Courier,monospace;">}</span></span></blockquote>
<span style="background-color: white;">Я также написал возможное решение этой задачи, если вдруг кому-то будет очень сложно. Скачать исходные файлы можно тут: <a href="http://goo.gl/lhPMg" target="_blank">JavaPractice03.zip</a> (3,4 KB)</span><br />
<span style="background-color: white;">Чтобы откомпилировать и запустить этот пример, выполните следующие команды: </span><br />
<blockquote class="tr_bq">
<span style="font-family: 'Courier New',Courier,monospace;"><span style="background-color: white;">cd <каталог_куда_распаковали_архив></span><br />
<span style="background-color: white;">cd src </span><br />
<span style="background-color: white;">javac *.java</span><br />
<span style="background-color: white;">java Program</span></span></blockquote>
<span style="background-color: white;">Также, если Вы уже умеете работать со средой разработки <a href="http://www.eclipse.org/" target="_blank">Eclipse</a>, то можете <a href="https://www.youtube.com/watch?v=XPDEXGvlYEU" target="_blank">импортировать</a> этот проект в нее и запустить. </span><br />
<br />
<span style="background-color: white;">В качестве <b>дополнительного задания</b>, можно написать отдельные класс <span style="font-family: 'Courier New',Courier,monospace;">Keyboard</span>, который будет содержать статические методы для ввода строки (String), целого числа (Integer) и дробного числа (Double). Методы по вводу чисел будет проверять, а число ли введено вообще, и выдавать сообщение об ошибке или требовать правильный ввод.</span><br />
<br />
<span style="background-color: white;">Ну и собственно видео:</span><br />
<span style="background-color: white;"><br /></span>
<br />
<div align="center">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/dLVquhA3TQ8" width="560"></iframe>
</div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com35tag:blogger.com,1999:blog-6797839624244344630.post-92029442045846621592012-06-16T21:20:00.001+03:002013-11-06T17:59:46.356+02:00Java Практика - Занятие 2<div class="separator" style="clear: both; text-align: center;">
<span style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaFqP9iqGGyxI4KfWorRFcml2PkqedSFKI1pmKuBZPdta-CTBAxDzkhWLRi0Xor0aWjiPyySYC6gJ16FJPdicERV9TMG1RwpoDwp26JA7azbZvcG6jmDJgw4VTpnAJ0-nE-2VKB59Z658/s1600/220px-Function_machine2.svg.png" /></span></div>
Второе занятие из курса <a href="https://www.youtube.com/playlist?list=PLD964614607573AFD&feature=plcp" target="_blank">Java Практика</a> я посвятил такому важному для каждого программиста явлению, как выделение части кода в отдельные <a href="https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0" target="_blank">подпрограммы</a> (<a href="https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)" target="_blank">функции</a>) с целью их многократного использования и устранения <a href="https://ru.wikipedia.org/wiki/%D0%94%D1%83%D0%B1%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BA%D0%BE%D0%B4%D0%B0" target="_blank">дублирования кода</a>. Само собой разумеется, что эти две причины - далеко не единственные, ради которых используют функции. Однако, наверное, они основные, если не вдаваться в сложные механизмы взаимодействия объектов в Java программе. Дополнительно, я остановился на способах передачи данных в функции. Конечно, пришлось немного забегать наперед, рассказывая про объекты в Java, ведь функции не могут существовать сами по себе (даже статические функции принадлежат классу), но много на объектах я не останавливался. Все-таки, основное, что надо вынести из этого урока - это то, что в программе необходимо выделять логически связанные блоки в отдельные подпрограммы, чтобы повторно их использовать, устранить дублирование кода и сделать программу более понятной и обозримой.<br />
<br />
Перед просмотром этого занятия можно посмотреть <a href="https://www.youtube.com/watch?v=CYUgc0EhqS4" target="_blank">Урок 4</a> из курса Java для тестировщиков, где я как раз рассказываю про объявление функций (методов класса), аргументы функций и возврат значений из них. Там, конечно, еще и много чего другого, так что <a href="https://www.youtube.com/watch?v=lGQxeGiqmKU" target="_blank">Урок 3</a> тоже посмотрите, если не совсем понятно, что такое объекты и "с чем их едят".<br />
<br />
Из, собственно, практики в этом занятии я немного остановился на заданиях из первого занятия. Также мы рассмотрели, что можно вынести в отдельные подпрограммы в алгоритмах сортировки массива. А также рассмотрели алгоритм бинарного поиска в массиве, реализация которого и есть следующим заданием.<br />
<br />
<div id="task">Итак, задания для самостоятельной работы:</div>
<ul>
<li>реализовать еще один <a href="http://algolist.manual.ru/sort/index.php" target="_blank">алгоритм сортировки</a> массива (отличный от того, что был реализован для предыдущего занятия)</li>
<li>реализовать алгоритм <a href="http://algolist.manual.ru/search/bin_search.php" target="_blank">бинарного поиска</a> элемента в отсортированном массиве.</li>
</ul>
<br />
Ну и собственно видео второго занятия, которое, кстати, было записано в <a href="https://ru.wikipedia.org/wiki/Full_HD" target="_blank">FullHD</a> :)<br />
<br />
<div align="center">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/86Whd3UFSCE" width="560"></iframe></div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com2tag:blogger.com,1999:blog-6797839624244344630.post-28014082223074751292012-06-09T21:50:00.000+03:002012-07-01T02:02:33.392+03:00Занятия по JavaИ вот я снова вернулся к преподаванию <a href="http://java.com/" target="_blank">Java</a>.
В очередной раз в компании, где я работаю, возникла необходимость
рассказать о языке программирования Java некоторым нашим сотрудникам.
Чтобы не повторятся и снова не рассказывать то, что и так уже известно и
доступно на <a href="http://www.youtube.com/ytkach" target="_blank">youtube</a>, мы решили в этом новом курсе сделать упор на
<b>практическое применение Java</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="133" ilo-full-src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC2eGLrQ4Z7m9rABdHxN6K7mwkufZFntz6MLe4JKkbxTvlG8Fk7FEuGw4CTVe5hq1T0ij7NxzrVFZ8ZvlLDSVbMnuHcCjQ77QamNmXRYEmYCE0OJcsSfMpAuOl7sp5ARR-R35Z2t40z8E/s200/0013-014-Stroitel.jpg" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC2eGLrQ4Z7m9rABdHxN6K7mwkufZFntz6MLe4JKkbxTvlG8Fk7FEuGw4CTVe5hq1T0ij7NxzrVFZ8ZvlLDSVbMnuHcCjQ77QamNmXRYEmYCE0OJcsSfMpAuOl7sp5ARR-R35Z2t40z8E/s200/0013-014-Stroitel.jpg" width="200" /></span></div>
Так как предыдущий курс <a href="https://www.youtube.com/playlist?list=PLB0276A0A62BDEF06&feature=plcp" target="_blank">Java для тестировщиков</a> был в основном
теоретическим и ознакомительным, то в этот раз занятия будут проходить
следующим образом. Слушатели сначала самостоятельно смотрят <a href="https://www.youtube.com/playlist?list=PLB0276A0A62BDEF06&feature=plcp" target="_blank">уроки на youtube</a> (не все сразу, а по одной или две), потом на занятии я некоторое
время резюмирую теоретический материал, на чем-то, возможно,
останавливаюсь подробнее или что-то добавляю, отвечаю на вопросы. Далее,
я разбираю какую-нибудь практическую задачку, решение которой
основывается на полученных теоретических знаниях. Ну и в конце я задаю
небольшое задание для самостоятельной работы.<br />
<br />
Как и в прошлый раз, видео я буду записывать и выкладывать на youtube,
объединяя их в отдельный <a href="https://www.youtube.com/playlist?list=PLD964614607573AFD&feature=view_all" target="_blank">плейлист</a>. Надеюсь, что наличие практической
составляющей поможет многим быстрее и лучше разобраться с Java, тем
более, что многие просили о различных задачах в многочисленных
комментариях.<br />
<br />
Итак, первое занятие из курса Java практика можно посмотреть ниже. Перед
просмотром этого видео, рекомендуется ознакомиться с <a href="https://www.youtube.com/watch?v=DKy4KzIn1qg&list=PLB0276A0A62BDEF06&index=1&feature=plpp_video" target="_blank">уроком 1</a> и <a href="https://www.youtube.com/watch?v=6pApP6TKxck&list=PLB0276A0A62BDEF06&index=2&feature=plpp_video" target="_blank">уроком 2</a>
из курса Java для тестировщиков. Обратите также внимание на <a href="https://www.youtube.com/all_comments?v=6pApP6TKxck" target="_blank">комментарии ко второму уроку</a>, где многие поправляли ошибки, которые я допускал.
Вообще, некоторые комментарии очень даже хорошие и полезные, особенно от
пользователя <a href="https://www.youtube.com/user/hazartilirot" target="_blank">hazartilirot</a> .<br />
<br />
<span style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="113" ilo-full-src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9tcBaXLe6VjrWl6BTJeKL_XhxJSgkNr1pfpY7EeWADgP9c93WtrQWbiv3b84-gEtL1-qtgRZ23pJyiAS9X4AqQtB2A3ZGGn5DEuA7aUW8c7kfBFIdfZMnbvGvXBQ1qJT0nrsSlzegamg/s200/456923.jpg" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9tcBaXLe6VjrWl6BTJeKL_XhxJSgkNr1pfpY7EeWADgP9c93WtrQWbiv3b84-gEtL1-qtgRZ23pJyiAS9X4AqQtB2A3ZGGn5DEuA7aUW8c7kfBFIdfZMnbvGvXBQ1qJT0nrsSlzegamg/s200/456923.jpg" width="200" /></span>
Задания для самостоятельной работы после первого занятия:<br />
<ol>
<li>Написать программу, которая выдает заданное число из
<a href="https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%B0_%D0%A4%D0%B8%D0%B1%D0%BE%D0%BD%D0%B0%D1%87%D1%87%D0%B8" target="_blank">последовательности Фибоначчи</a>. </li>
<li>Написать программу, которая <a href="https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8" target="_blank">сортирует</a> массив чисел.</li>
</ol>
Естественно, при написании программ не желательно использовать
встроенные механизмы Java для сортировки или поиска числа Фибоначчи :)<br />
<br />
<div align="center">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/V9qzo32u0Z4" width="560"></iframe>
</div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com9tag:blogger.com,1999:blog-6797839624244344630.post-3832516833728151422011-11-15T14:45:00.001+02:002011-11-15T15:38:49.201+02:00CDMA модем Huawei и Ubuntu Linux<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDOeNtn8ACNE0EMW6-R12c51KV5OVpbLcvGz3YAxrs9WtJU1I_3Ls2RmjRgAccwZNvq_wTL4sgqsqMkHyIm-GxwdvlTtq8rcOK4Ne9gZLbLtfK00bnrofl2QnYN186i9JG2UBadqvwSUg/s1600/huaweie1750.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" /></div>
В связи с жизненной
необходимостью подключил себе <a href="http://www.intertelecom.ua/ru/tariffs/internet/tarifi-revb" target="_blank">услугу</a>
мобильного высокоскоростного доступа
в интернет от провайдера, которым уже
давно пользуюсь. Данный провайдер
использует технологию <a href="http://ru.wikipedia.org/wiki/CDMA" target="_blank">CDMA</a>,
и для пользования высокоскоростным
интернетом пришлось приобрести новый
модем. Имя ему <a href="http://www.intertelecom.ua/ru/oborudovanue/modems/huawei/Huawei-EC306" target="_blank">Huawei
EC 306</a>. Интересно это устройство тем,
что при подключении к компьютеру оно
распознается как флеш-накопитель, на
котором находятся Windows-драйвера. Однако
внутри устройства также находится
SIM-карта оператора, и оно может работать
как модем. Драйверов для Linux, естественно,
нету, да они и не нужны. Необходимо всего
лишь переключить режим работы устройства...<br />
<br />
<br />
<div style="text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkTzi1a0vqQX6SKBj-4axsKfuv6ccGjmPH3EWsLAJISFaU1mZpbIlNeAwTqyve1BUZ5B4dRp4EwDEeK47031u2Q43bqRxgBuaAnU2P_71JnulkmiIr9TNbVB3VrNOkM46I89UdHzC-heU/s1600/22222.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkTzi1a0vqQX6SKBj-4axsKfuv6ccGjmPH3EWsLAJISFaU1mZpbIlNeAwTqyve1BUZ5B4dRp4EwDEeK47031u2Q43bqRxgBuaAnU2P_71JnulkmiIr9TNbVB3VrNOkM46I89UdHzC-heU/s200/22222.PNG" width="172" /></a></div>
На Windows-системе все
оказывается очень просто. На флеш-карте
находятся драйвера. Установка запускается
автоматически, когда подключается
устройство. После установки будет
доступно приложение, запустив которое
можно подключаться к интернету. Приложение
называется <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkTzi1a0vqQX6SKBj-4axsKfuv6ccGjmPH3EWsLAJISFaU1mZpbIlNeAwTqyve1BUZ5B4dRp4EwDEeK47031u2Q43bqRxgBuaAnU2P_71JnulkmiIr9TNbVB3VrNOkM46I89UdHzC-heU/s1600/22222.PNG" target="_blank">Mobile Partner</a>, написанное все той
же компанией Huawei, и видимо, распространяется
с ее модемами, а разные операторы уже
изменяют текст интерфейса и картиночки
на свои.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXwpNruL-SNNf4tbXnM3pHDvG1DDaRnsmLVQNOrIAm9GuGRIF-NMDWsDmCZdCgP9jxWTFU8bNVI8RDFa0YjI_zDzxB5IVkp640eEjeB6DoURvK1r5wVKw0K17AkmBEsV4tU2F-BtX-UYM/s200/Ubuntu_Logo_Plastic_Version_by_qinjuehang.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" width="100" /></div>
На Linux-системе драйвера
для модема не нужны вообще. Это
<a href="http://ru.wikipedia.org/wiki/USB" target="_blank">универсальное
последовательное устройство</a>, с которым
Linux умеет работать — все, что нужно, это
настроить модем. В операционной системе
<a href="http://ubuntu.com/" target="_blank">Ubuntu</a> такие
настройки хорошо автоматизированы, а
<a href="http://ru.wikipedia.org/wiki/NetworkManager" target="_blank">менеджер
сетевых подключений</a> даже умеет
подключаться к моему оператору через
выбранное устройство. Выходит, что нужно
только заставить систему распознавать
устройство как модем, а не как
флеш-накопитель.<br />
<br />
<br />
Можно установить
программу Mobile Partner на Ubuntu. <a href="http://alexvolkov.ru/mobile-partner-pod-linuks-dlya-modema-huawei-e1550.html" target="_blank">Вот
здесь</a> я, даже, нашел ссылку на скрипт
установки (<i>я скрипт не проверял, так
что запускайте его на свой страх и
риск!</i>). А потом <a href="http://ubuntuforums.org/showpost.php?p=7622263&postcount=3" target="_blank">вот
тут на ubuntuforums.org</a> и еще <a href="http://habrahabr.ru/qa/399/" target="_blank">вот
тут на habrahabr.ru</a> в комментариях я нашел,
что устанавливать программу нет смысла.
Достаточно указать системе, чтобы она
переключала режим работы устройства.
Необходимо выполнить следующие шаги:<br />
<br />
<br />
<ol>
<li>Открываем терминал
и выполняем команду <span style="font-family: 'Courier New', monospace;"><b>lsusb</b></span><br />В
результате получим список USB устройств,
подключенных к компьютеру.<br /><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">~$ lsusb
<br />Bus
007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Bus
004 Device 002: ID 046d:c018 Logitech, Inc. Optical Wheel Mouse
</span><br />
<span class="Apple-style-span" style="background-color: #fff2cc; font-family: 'Courier New', Courier, monospace; font-size: x-small;">Bus 003 Device 001: ID <b>12d1:1505</b>
Huawei Technologies Co., Ltd.</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Bus
003 Device 002: ID 1d6b:0001 Linux Foundation 1.1 root hub
</span><br />
<br />
</li>
<li>В
полученном списке находим модем и
обращаем вниманием на его ID. Первые
четыре символа (в моем случае это 12d1) —
это идентификатор производителя. Вторые
четыре (в моем случае это 1505) — это
идентификатор устройства.<br />
<br />
</li>
<li>Теперь
выполняем в терминале следующую команду (все одной строчкой),
заменив идентификаторы производителя
и устройства на свои:<br /><br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">echo 'SUBSYSTEM=="usb",
SYSFS{idProduct}=="<b>1505</b>", SYSFS{idVendor}=="<b>12d1</b>",
RUN+="/lib/udev/modem-modeswitch --vendor 0x<b>12d1</b> --product
0x<b>1505</b> --type option-zerocd"' | sudo tee
/etc/udev/rules.d/45-huawei<b>1550</b>.rules</span><br />
<br />
После
выполнения этой команды в каталоге
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">/etc/udev/rules.d/</span> появится файл <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">45-huawei1550.rules</span>,
команды из которого будут прочитаны,
при подключении устройства к компьютеру.<br />
<br />
</li>
<li>Вынимаем
устройство, вставляем его снова — и у
вас уже не флешка, а модем, подключенный
к компьютеру. Дальше все просто — правой
кнопкой на значке сети, Редактировать
подключения, закладка Мобильные
подключения, Кнопка Добавить — выбираем
свою страну, провайдера и все! :)<br />
</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<b>P.S.</b> Немного о скорости
для тех, кому интересно. Заявленная
оператором скорость передачи данных в
сети <a href="http://ru.wikipedia.org/wiki/EVDO" target="_blank">EVDO</a>
Rev.B+: загрузка до 14,7 Мбит/с, передача до
5,4 Мбит/с. В реальности, конечно, все
зависит от загруженности сети, удаленности
от базовой станции, и количества осадков
в амазонской равнине. Тестируя связь в
центре Киева в полдень, загружая ролики
с youtube, файлы с ex.ua и т.д. скорость у
меня прыгала от 1 до 6 Мбит/с, что очень
даже недурно, как для мобильного
интернета.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhImUtZ7W2d1cZq1lExmBLxcje-UtQkQ1XENh_Gf7Lh_XLiBN30jqcge-iBtuw5xUhuNu6_oP0e7lfR2XNB-lzv8rYVBcLJP8gBIkpo_9ZUlBFZFiwo_PZG9Tg4SQ6__A1ofNIOv5I1iW4/s1600/104789.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhImUtZ7W2d1cZq1lExmBLxcje-UtQkQ1XENh_Gf7Lh_XLiBN30jqcge-iBtuw5xUhuNu6_oP0e7lfR2XNB-lzv8rYVBcLJP8gBIkpo_9ZUlBFZFiwo_PZG9Tg4SQ6__A1ofNIOv5I1iW4/s200/104789.png" width="200" /></a></div>
<br />Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com7tag:blogger.com,1999:blog-6797839624244344630.post-15869526452913025852011-10-24T00:30:00.000+03:002011-10-24T00:30:43.479+03:00javax.net.ssl.SSLException: bad_record_mac<div>
<div class="separator" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;">
<img border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTK7ycg0qwH2_GE7HP80q9BcTIpQV5ZK6gXVliAoQsrFdGOiENIxkY4_taEeO6hlrlQPf9a2JRkORjb0F4Y74DaEfUoeEbKibSVC_d0Gnglqbv7N6V8gUvoMezaR04p3ve6ioPZoVeJVA/s200/ssl.jpg" width="200" /></div>
While writing a java net application I've encountered an interesting problem, which solution was not very trivial. The task was to connect to one website, parse the output, and write extracted information to a file. At first glance the task is "<a href="http://en.wikipedia.org/wiki/Piece_of_Cake" target="_blank">a piece of cake</a>", but the problem appeared at the stage of connecting to the web site. The site uses the <a href="http://en.wikipedia.org/wiki/HTTP_Secure" target="_blank">https protocol</a>, and I had to use something more complex than basic java's <a href="http://download.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html" target="_blank">HttpURLConnection</a>. I've tried to use java's <a href="http://download.oracle.com/javase/6/docs/api/javax/net/ssl/HttpsURLConnection.html" target="_blank">HttpsURLConnection</a>, but while connecting to the site I received the following exception, which got me stuck me for a while: <b><a href="http://download.oracle.com/javase/6/docs/api/javax/net/ssl/SSLException.html" target="_blank">javax.net.ssl.SSLException</a>: bad_record_mac</b>. Eventually the problem was solved and the solution is described below.
</div>
<div>
<br /></div>
<div>
Firstly, I will describe classes that were used to perform the connection. I've decided not to use internal java api directly and to look for some 3-rd party library, because besides connecting to the site, I had to execute some post and get queries to get required information and I wanted to do that with less pain. I chose to use the <a href="http://hc.apache.org/httpcomponents-client-ga/index.html" target="_blank">HttpClient</a> library from Apache commons project. Here is the basic connection example that uses that library:
</div>
<div>
<br /></div>
<pre style="background: #f6f8ff; color: #000020;">HttpClient httpclient <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> DefaultHttpClient<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">try</span> <span style="color: #406080;">{</span>
HttpGet httpget <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> HttpGet<span style="color: #308080;">(</span><span style="color: #1060b6;">"http://www.google.com/"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
ResponseHandler<span style="color: #308080;"><</span><span style="color: #6679aa; font-weight: bold;">String</span><span style="color: #308080;">></span> responseHandler <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> BasicResponseHandler<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #6679aa; font-weight: bold;">String</span> responseBody <span style="color: #308080;">=</span> httpclient<span style="color: #308080;">.</span>execute<span style="color: #308080;">(</span>httpget<span style="color: #308080;">,</span> responseHandler<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span> <span style="color: #200080; font-weight: bold;">finally</span> <span style="color: #406080;">{</span>
httpclient<span style="color: #308080;">.</span>getConnectionManager<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">.</span>shutdown<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
</pre>
<div>
<br /></div>
<div>
However, it won't work with some https websites. It does work with many of them, but some of them fail with different ssl exceptions. The site I was connecting to firstly failed with the following exception:
</div>
<div>
<br /></div>
<pre style="background: #f6f8ff; color: #000020;">javax<span style="color: #308080;">.</span>net<span style="color: #308080;">.</span>ssl<span style="color: #308080;">.</span>SSLPeerUnverifiedException<span style="color: #308080;">:</span> peer not authenticated
</pre>
<div>
<br /></div>
<div>
That means that the certificates were not verified correctly. Therefore, I had to implement more complex solution to handle different SSL cases. Here you might look for some other 3-rd party library that will handle secure socket connections by itself, however you might not get the full control. You can use this <a href="http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e537" target="_blank">advice</a> from the HttpClient manual and implement everything on your own. Eventually, everything can work fine OR you might get the exception mentioned at the beginning. If you're lucky one - my congratulations. If not - keep reading :)
</div>
<div>
<br /></div>
<div>
In order to get the better understanding I decided to implement everything based on HttpClient and then debug it to see where it fails. I didn't care about checking the certificates and trusting the connection and just wanted to get the page contents. I've used examples from <a href="http://javaskeleton.blogspot.com/2010/07/avoiding-peer-not-authenticated-with.html" target="_blank">this blog post</a> that I found pretty interesting. Therefore, I've created <b>MyConnectionFactory</b> that extends <a href="http://download.oracle.com/javase/6/docs/api/javax/net/ssl/SSLSocketFactory.html" target="_blank">SSLSocketFactory</a>. It initialized the SSL context with my own <a href="http://download.oracle.com/javase/6/docs/api/javax/net/ssl/TrustManager.html" target="_blank">TrustManager</a> and then uses it to create <a href="http://download.oracle.com/javase/6/docs/api/javax/net/ssl/SSLSocket.html" target="_blank">secure sockets</a>.
</div>
<div>
<br /></div>
<pre style="background: #f6f8ff; color: #000020;"><span style="color: #200080; font-weight: bold;">public</span> <span style="color: #200080; font-weight: bold;">static</span> <span style="color: #200080; font-weight: bold;">class</span> MySSLSocketFactory <span style="color: #200080; font-weight: bold;">extends</span> SSLSocketFactory <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">private</span> SSLContext sslContext <span style="color: #308080;">=</span> SSLContext<span style="color: #308080;">.</span>getInstance<span style="color: #308080;">(</span><span style="color: #1060b6;">"SSLv3"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">public</span> MySSLSocketFactory<span style="color: #308080;">(</span><span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">throws</span> <span style="color: #6679aa; font-weight: bold;">Exception</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">super</span><span style="color: #308080;">(</span><span style="color: #308080;">(</span>TrustStrategy<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">null</span><span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">new</span> AllowAllHostnameVerifier<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
sslContext<span style="color: #308080;">.</span>init<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">null</span><span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">new</span> TrustManager<span style="color: #308080;">[</span><span style="color: #308080;">]</span> <span style="color: #406080;">{</span> myTrustManager <span style="color: #406080;">}</span><span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">null</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #200080; font-weight: bold;">public</span> <span style="color: #6679aa; font-weight: bold;">Socket</span> createSocket<span style="color: #308080;">(</span><span style="color: #6679aa; font-weight: bold;">Socket</span> socket<span style="color: #308080;">,</span> <span style="color: #6679aa; font-weight: bold;">String</span> host<span style="color: #308080;">,</span> <span style="color: #7779bb;">int</span> port<span style="color: #308080;">,</span> <span style="color: #7779bb;">boolean</span> autoClose<span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">throws</span> <span style="color: #6679aa; font-weight: bold;">IOException</span><span style="color: #308080;">,</span> <span style="color: #6679aa; font-weight: bold;">UnknownHostException</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">return</span> sslContext<span style="color: #308080;">.</span>getSocketFactory<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">.</span>createSocket<span style="color: #308080;">(</span>socket<span style="color: #308080;">,</span> host<span style="color: #308080;">,</span> port<span style="color: #308080;">,</span> autoClose<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #200080; font-weight: bold;">public</span> <span style="color: #6679aa; font-weight: bold;">Socket</span> createSocket<span style="color: #308080;">(</span><span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">throws</span> <span style="color: #6679aa; font-weight: bold;">IOException</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">return</span> sslContext<span style="color: #308080;">.</span>getSocketFactory<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">.</span>createSocket<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #406080;">}</span>
</pre>
<div>
<br /></div>
<div>
I created the implementation of TrustManager that basically does nothing in its methods - so it skipped any security check. In other circumstances its probably not a wise thing to do, but for my task that was enough, so I didn't want to complicate things.
</div>
<div>
<br /></div>
<pre style="background: #f6f8ff; color: #000020;">TrustManager myTrustManager <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> X509TrustManager<span style="color: #308080;">(</span><span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">public</span> <span style="color: #7779bb;">void</span> checkClientTrusted<span style="color: #308080;">(</span>X509Certificate<span style="color: #308080;">[</span><span style="color: #308080;">]</span> chain<span style="color: #308080;">,</span> <span style="color: #6679aa; font-weight: bold;">String</span> authType<span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">throws</span> CertificateException <span style="color: #406080;">{</span> <span style="color: #406080;">}</span>
<span style="color: #200080; font-weight: bold;">public</span> <span style="color: #7779bb;">void</span> checkServerTrusted<span style="color: #308080;">(</span>X509Certificate<span style="color: #308080;">[</span><span style="color: #308080;">]</span> chain<span style="color: #308080;">,</span> <span style="color: #6679aa; font-weight: bold;">String</span> authType<span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">throws</span> CertificateException <span style="color: #406080;">{</span> <span style="color: #406080;">}</span>
<span style="color: #200080; font-weight: bold;">public</span> X509Certificate<span style="color: #308080;">[</span><span style="color: #308080;">]</span> getAcceptedIssuers<span style="color: #308080;">(</span><span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">return</span> <span style="color: #200080; font-weight: bold;">null</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #406080;">}</span>
</pre>
<div>
<br /></div>
<div>
Then I put everything together by registering my socket factory for the port 443 connections and then creating the HttpClient with my connection manager. The code to setup HttpClient looks like this:
</div>
<div>
<br /></div>
<pre style="background: #f6f8ff; color: #000020;"><span style="color: #200080; font-weight: bold;">private</span> <span style="color: #200080; font-weight: bold;">static</span> HttpClient setupHttpClient() <span style="color: #200080; font-weight: bold;">throws</span> Exception <span style="color: #406080;">{</span>
SSLSocketFactory sf <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> MySSLSocketFactory<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
SchemeRegistry registry <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> SchemeRegistry<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
registry<span style="color: #308080;">.</span>register<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">new</span> Scheme<span style="color: #308080;">(</span><span style="color: #1060b6;">"http"</span><span style="color: #308080;">,</span> <span style="color: #008c00;">80</span><span style="color: #308080;">,</span> PlainSocketFactory<span style="color: #308080;">.</span>getSocketFactory<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
registry<span style="color: #308080;">.</span>register<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">new</span> Scheme<span style="color: #308080;">(</span><span style="color: #1060b6;">"https"</span><span style="color: #308080;">,</span> sf<span style="color: #308080;">,</span> <span style="color: #008c00;">443</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
ClientConnectionManager ccm <span style="color: #308080;">=</span> <span style="color: #200080; font-weight: bold;">new</span> ThreadSafeClientConnManager<span style="color: #308080;">(</span>registry<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">return</span> <span style="color: #200080; font-weight: bold;">new</span> DefaultHttpClient<span style="color: #308080;">(</span>ccm<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
</pre>
<div>
<br /></div>
<div>
With this code I was able to connect to my https website, but I started to get the exception javax.net.ssl.SSLException: bad_record_mac. And that's where all the fun started - looking into Internet and debugging to get the solution.
</div>
<div>
<br /></div>
<div>
First of all, I've downloaded source code for HttpClient and started to debug to see where exactly the problem occurs. It was interesting to find out that the problem occurs when the <b>getSession()</b> method is called on <b>SSLSocket</b>. Java performs the <a href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer#TLS_handshake_in_detail" target="_blank">SSL handshake</a> and it fails. So, I went to the Internet to find the solution, because very likely the problem was solved before.
</div>
<div>
<br /></div>
<div>
Quite interesting looks the following <a href="http://stackoverflow.com/questions/4496941/curl-php-request-executes-50-of-the-time/4505050#4505050" target="_blank">stackoverflow answer</a> to similar question, which says that the problem could be due to the <a href="http://en.wikipedia.org/wiki/Load_balancing_(computing)" target="_blank">load balancing</a>, when the MAC address changes during negotiation. It could be the reason that the problem occurs sometimes. However, in my case the exception appeared every time, so I continued to search.
</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;">
<img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw09TRGxvXUgHTV6xVxQ7xjHRtr9IOotE3SmpESwD3vGlwMuuFq61JCQppnLlxA5V2mk0hyphenhyphenT-Poqvf1kOlAOxfz0O4rXfTTJLHVhRhZO4f9sz5LKMw4OUn1l8M6sdO2_zO8PtJNpu3Hlc/s200/privacy.jpg" width="200" /></div>
Eventually, I found two different sources that pointed out for the reason and how to overcome it: <a href="http://wiki.almworks.com/display/kb/bad_record_mac+error+when+connecting+to+SSLv3-only+server" target="_blank">one</a> is the knowledge base article for <a href="http://en.wikipedia.org/wiki/JIRA" target="_blank">JIRA</a> client connecting to server, and <a href="http://www.coderanch.com/t/430224/sockets/java/javax-net-ssl-SSLException-bad" target="_blank">another</a> is last coderanch answer. The problem appears because Java tries all kinds of <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#History_and_development" target="_blank">secure socket protocols</a> (TLS, SSLv2, SSLv3, etc.) even if only one is supported by the server. This results in the aborted connection. Trapping this error can be hard if you don't have access to the server. But if not the load balancing, then the reason could be either unsupported protocol, or unsupported <a href="http://en.wikipedia.org/wiki/Cipher_algorithm" target="_blank">cipher algorithm</a>.
</div>
<div>
<br /></div>
<div>
<b>The solution is to configure Java in such a way that it will use only one secure socket protocol for communication</b>. Therefore, in both <i>createSocket</i> methods of <i>MySSLSocketFactory</i> I've added the following code after creating sockets:
</div>
<div>
<br /></div>
<pre style="background: #f6f8ff; color: #000020;"><span style="color: #308080;">(</span><span style="color: #308080;">(</span>SSLSocket<span style="color: #308080;">)</span> socket<span style="color: #308080;">)</span><span style="color: #308080;">.</span>setEnabledProtocols<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">new</span> <span style="color: #6679aa; font-weight: bold;">String</span><span style="color: #308080;">[</span><span style="color: #308080;">]</span> <span style="color: #406080;">{</span> <span style="color: #1060b6;">"SSLv3"</span> <span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #308080;">(</span><span style="color: #308080;">(</span>SSLSocket<span style="color: #308080;">)</span> socket<span style="color: #308080;">)</span><span style="color: #308080;">.</span>setUseClientMode<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">true</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
</pre>
<div>
<br /></div>
<div>
And it worked! That solved my problem. The handshake went fine, the connection went fine, and I was able to do my task. In conclusion, I can say, that while writing this blog post, I could not reproduce the problem. :) So, maybe, it really has something to do with load balancing - I didn't dig into it. In any case, debugging of SSL problems can be tough, so enabling Java net log by calling <span style="background-attachment: initial; background-clip: initial; background-color: #f6f8ff; background-image: initial; background-origin: initial; color: #000020; font-family: 'Courier New', Courier, monospace;"><span style="color: #6679aa; font-weight: bold;">System</span><span style="color: #308080;">.</span>setProperty<span style="color: #308080;">(</span><span style="color: #1060b6;">"javax.net.debug"</span><span style="color: #308080;">,</span> <span style="color: #1060b6;">"all"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span></span> can be very helpful.<br />
<br />
The testing program with working example with SSL connection can be downloaded here: <a href="http://goo.gl/JFdw5" target="_blank">http://goo.gl/JFdw5</a></div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com6tag:blogger.com,1999:blog-6797839624244344630.post-41307491601183702682010-11-10T16:51:00.003+02:002011-09-16T13:10:17.099+03:00Лекции по JavaКомпания, в которой я работаю, решила повысить уровень квалификации некоторых своих сотрудников, а именно тех, что работают в области тестирования программного обеспечения, а также проектных менеджеров, и предложила провести для них курсы по языку программирования <a href="http://java.com/">Java</a>. Для них Java необходима по разным причинам, но в основном, потому что они не могут выполнять некоторые задачи в рамках работы над проектами, в которых используется Java. Основная цель - научиться понимать Java-код и писать несложные <a href="http://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5">Unit-тесты</a>. Т.е. стать полноценными программистами от них никто не требует. Так как они все технически подкованы и большинство имеют опыт программирования на Visual Basic, то предполагается, что разобраться с Java до начально-продвинутого уровня им будет под силу. И вот вспомнив о моем опыте преподавания, компания предложила мне провести такие курсы для небольшой группы из 10 человек.<br />
<br />
Курс рассчитан на N-ое количество занятий. Пока что, до Нового Года, а там видно будет. Занятия будут проходить 2 раза в неделю, поэтому как минимум 10 занятий будет точно. Основное на что надо дать упор - это особенности языка, основные классы, знакомство с библиотеками. Чтобы долго не мудрить, я подготовил программу курса, основываясь на <a href="http://download.oracle.com/javase/tutorial/">Java Tutorial</a> - убрал некоторые специфические вопросы и добавил некоторые вещи, согласно пожеланиям. Программу курса можно посмотреть <a href="https://docs.google.com/document/edit?id=1_7d23HMCtiMz-bu41mkae9VDXW9xEqJiZn1ZYMN6KoM&hl=en_GB&authkey=CMO9o7UL">здесь</a>. Пока что будем следовать ей, и по ходу корректировать.<br />
<br />
После проведения нескольких занятий хочется отметить некоторые приятные отличительные особенности от преподавания в ВУЗе:<br />
<br />
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNJGhLw6zm_MgSCD8sKeekFOcvuxG6YtFCt6wAdJKaCNt_rXwXqf95XOuJ9xxyEqyvVvCZUnycgR_dOK3Y3TfZ5Q69UoD5sTFDDWwpjKpO6sWntOdqexmm0FpSBgjLyRwOC6Tg3MCfzU0/s1600/B81CBCD8D22241F59DC112761D130FAC.ashx.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" /><br />
<ul>
<li><b>Небольшая и заинтересованная аудитория</b>. Все-таки читать курс полсотне студентов, у которых совершенно разный уровень подготовки и, что важно, совершенно разные причины присутствия на лекции - это совсем другое. Сложнее заинтересовать, сложнее удержать внимание, сложнее донести материал так, чтобы слабым было понятно, а сильным не скучно. Здесь же на курсах - людей не много, все хотят, задают вопросы, сами занимаются и т.д.<br />
<br />
</li>
<li><b>Интерактивная электронная доска</b>. Благодаря этому чуду техники "жить стало лучше, жить стало веселее". Занятия проходят в переговорной комнате, где у нас установлена такая доска - <a href="http://smarttech.com/us/Solutions/Education+Solutions/Products+for+education/Interactive+whiteboards+and+displays/SMART+Board+interactive+whiteboards/685ix+for+education">SMART Board</a>. Доска подключена к компьютеру и ее можно использовать как большой экран. На ней можно рисовать специальными маркерами, двигать объекты руками, сохранять нарисованное и т.д. Если комната с такой доской занята, то занятия проходят в другой переговорке, где обычная доска и маркеры. Однако, даже это лучше, чем обычная доска и мел. Что ж, у образования нашей страны нету денег на такие "штучки", однако есть гранты и меценаты. Университет, в котором я раньше работал, участвовал в программе по гранту, которая направленна на внедрение командной разработки в процесс подготовки программистов. По этому гранту университет получил некоторое оборудование, среди которого и такая интерактивная доска. За два года работы там я никогда не видел, чтобы доска включалась, зато часто видел, как доску выставляли на показ, когда приезжали "дяди" и кафедра с университетом перед ними хвастались. Что ж, можно долго спорить о причинах такой политики, но факт есть факт: в университете доска была, но пользоваться ей было нельзя, а здесь доска есть и пользуются ей все. Красота!</li>
</ul>
Так как никакой конфиденциальной информации на курсах я не раскрываю, то я подумал, а почему бы не поснимать все это на видео и сделать доступным для общественности. Во-первых, ребята не всегда могут посещать все занятия без пропусков из-за разной загруженности по работе, и видео поможет им оставаться "в строю". Во-вторых, возможно, кому-то еще этот курс сможет помочь выучить Java. Так что в записях этого блога буду выкладывать видео занятий, объединенных по темам.<br />
<br />
Итак, видео первого занятия, где происходит знакомство с Java, языком программирования, JVM, с тем, что это такое и с чем его едят.<br />
<div class="separator" style="clear: both; text-align: -webkit-auto;">
<br /></div>
<div align="center">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/DKy4KzIn1qg" width="560"></iframe>
</div>
Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com6tag:blogger.com,1999:blog-6797839624244344630.post-29321971759025978652009-12-21T18:19:00.001+02:002009-12-21T22:14:10.523+02:00Installing X.509 certificates on Nokia S60 3rd edition device<div style="margin-bottom: 0cm;">Sometimes you need to install your own <a href="http://en.wikipedia.org/wiki/X.509" target="_blank">X.509</a> certificate on the phone in order to authorize some web site, Exchange server, or installed software, or in general to use <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security">TLS (SSL)</a> connection. According to the <a href="http://www.forum.nokia.com/info/sw.nokia.com/id/a60ed5ab-c2fc-486c-89d0-2695b67ffec4/Installing_Certificates_to_S60_3rd_Edition_Devices_v1_1_en.pdf.html" target="_blank">guide</a>, provided on Nokia forums – it a piece of cake! However, sometimes problems may arise, and you start wondering about what can go wrong. The next thing you do is try to find the answer somewhere on the Internet. Well, you'll get a whole bunch of different posts about positive or negative experience, you'll find different solutions that are sometimes weird, sometimes don't work, and sometimes work but not on your phone. In general, most solutions are correct, you just need to pay attention to one <i>nobody-ever-mentioned</i> thing.<br />
</div><br />
<div style="margin-bottom: 0cm;">At first, a small amount of theory, so you'll know what I am talking about. X.509 certificate files have several extensions. Here is the <a href="http://en.wikipedia.org/wiki/X.509#Certificate_filename_extensions" target="_blank">description from Wikipedia</a> for the most common:<br />
</div><br />
<ul><li><b>.pem</b> - Base64 encoded DER certificate, enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" </li>
<li><b>.cer, .crt, .der</b> - usually in binary DER form, but Base64-encoded certificates are common too</li>
<li><b>.p12</b> - PKCS#12, may contain certificate(s) (public) and private keys (password protected) </li>
<li><b>.pfx</b> - PFX, predecessor of PKCS#12 (but most of the time the actual data is PKCS#12, only the extension is kept)</li>
</ul><br />
<div style="margin-bottom: 0cm;">If you are not into technical very much, you just need to know that <b>.pem</b> files are <u>text files</u>. So you can open them in any text editor (like GEdit or Notepad) and see bunch of letters and numbers after the first line, which says “-----BEGIN CERTIFICATE-----”. Those letters and numbers is actually a specially encoded <span style="text-decoration: none;">binary </span>certificate. Now, the files with extensions <b>.cer, .crt, .der</b> are usually (but not always!) <u>binary files</u>. That means that you cannot view their contents with usual text editor. But pay attention to what is being said at the end for this kind of files: “... but Base64-encoded certificates are common too”! That means, that you can have a certificate file with, for example, <b>.cer</b> extension, but it will be a <span style="font-style: normal;"><u>text file</u></span> actually encoded as <b>.pem</b> file! And, what's the difference, you ask, why should I care?<br />
</div><br />
<div style="margin-bottom: 0cm;">Well, here we came to the most interesting part. Nokia phones on <a href="http://en.wikipedia.org/wiki/S60_platform" target="_blank">S60 3<sup>rd</sup> edition platform</a> <b>cannot import .pem certificates</b>! They <b>cannot import certificates</b> that are represented <b>as text files</b>. You need a binary DER encoded file. And what's really exciting – you can have a .cer, .crt, or even .der file, but it will be a text file that was renamed from .pem! Well, your computer web browser will cope with it just fine. You computer mailing program will cope with it just fine, too. But not your Nokia phone!<br />
</div><br />
<div style="margin-bottom: 0cm;">If you are still wondering on “how do I know what kind of certificate file I have?”, then try to do a simple thing. Open the file with any text editor and see: if it opens correctly and has the first line as “-----BEGIN CERTIFICATE-----”, then this is a <b>text</b> <b>.pem</b> file. If it doesn't open correctly or has something really crazy inside – then it is probably a <b>binary .der</b> file.<br />
</div><br />
<div style="margin-bottom: 0cm;">If you have a binary certificate file, then just transfer it to the phone and open with phone's File Manager. It will ask you to import the certificate. Just like the mentioned <a href="http://www.forum.nokia.com/info/sw.nokia.com/id/a60ed5ab-c2fc-486c-89d0-2695b67ffec4/Installing_Certificates_to_S60_3rd_Edition_Devices_v1_1_en.pdf.html">tutorial</a> says. What if you have a text certificate file? Then you should convert it to binary representation. There is an open source and <i>free</i><span style="font-style: normal;"> program that can do it for you, called <a href="http://www.openssl.org/" target="_blank">OpenSSL</a>. A compiled version of <a href="http://www.slproweb.com/products/Win32OpenSSL.html" target="_blank">OpenSSL for Windows can be found here</a>. Ubuntu users just type in terminal: </span><span style="font-family: Courier New,monospace;"><span style="font-style: normal;">sudo apt-get install openssl</span></span><span style="font-style: normal;">. </span> <br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-style: normal;">So, you've got the program! Next thing you do is type in terminal the following command:</span><br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-family: Courier New,monospace;">openssl x509 -outform der -in <i>certificate.pem</i> -out <i>certificate.der</i></span><br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-style: normal;">In place of </span><i>'certificate.pem' </i><span style="font-style: normal;">you should put your text certificate file (it can have extensions </span><span style="font-style: normal;"><b>.pem</b></span><span style="font-style: normal;">, </span><span style="font-style: normal;"><b>.cer</b></span><span style="font-style: normal;">, </span><span style="font-style: normal;"><b>.crt</b></span><span style="font-style: normal;">, </span><span style="font-style: normal;"><b>.der</b></span><span style="font-style: normal;"> but it should be text file) and in place of </span><i>'certificate.der'</i><span style="font-style: normal;"> you just put any name you want. After executing this command (pressing Enter in terminal after typing it there) you should get in your directory a file named </span><i>'certificate.der'</i><span style="font-style: normal;"> (or whatever you've put there), which will be a </span><span style="font-style: normal;"><u>binary</u></span><span style="font-style: normal;"> </span><span style="font-style: normal;"><u>DER encoded certificate file</u></span><span style="font-style: normal;">. After that you do the same thing that I wrote before – transfer file to the phone and open it with File Manager. And you're done!</span><br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-style: normal;">Now, lets mention the </span><span style="font-style: normal;"><b>.p12</b></span><span style="font-style: normal;"> files. As I said before that are the binary files containing public certificate and password-protected private key. According to the already beloved Nokia guide this kind of files should be supported for installing on the phone. Well, not necessarily. In fact, unfortunately my Nokia N73 phone with the latest firmware does not import .p12 certificate files. I don't know why. Nokia support does not know either. I didn't dig it deeper into the problem, because I actually didn't need to install the certificate with private key – I probably will not decrypt any content with my phone that was signed or encrypted with public certificate (that is why you actually need a private key). But if you still need to import just the certificate from the .p12 file, you need to extract it first. The following command can be used:</span><br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-family: Courier New,monospace;">openssl pkcs12 -in </span><span style="font-family: Courier New,monospace;"><i>keyStore.p12</i></span><span style="font-family: Courier New,monospace;"> -out </span><span style="font-family: Courier New,monospace;"><i>certificate.pem</i></span><span style="font-family: Courier New,monospace;"> -nodes -nokeys </span> <br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-style: normal;">In place of </span><i>'keyStore.p12'</i><span style="font-style: normal;"> you put the name of your .p12 file and in place of </span><i>'certificate.pem'</i><span style="font-style: normal;"> you put any name. After executing this command you will get a </span><span style="font-style: normal;"><u>text certificate file</u></span><span style="font-style: normal;">. Please, pay attention – it will be a </span><span style="font-style: normal;"><b>text certificate file</b></span><span style="font-style: normal;"><span style="font-weight: normal;">. You will need to convert it to binary format with the command mentioned before.</span></span><br />
</div><br />
<div style="margin-bottom: 0cm;"><span style="font-style: normal;"><span style="font-weight: normal;">Well, that's about it! Now you should have no problems with installing your own X.509 certificate files on the Nokia phone. I didn't test the other versions of Symbian OS for the support of text certificate files, because I do not have many Nokia phones, except my own N73 :) But I think that S60 4</span></span><sup><span style="font-style: normal;"><span style="font-weight: normal;">th</span></span></sup><span style="font-style: normal;"><span style="font-weight: normal;"> and 5</span></span><sup><span style="font-style: normal;"><span style="font-weight: normal;">th</span></span></sup><span style="font-style: normal;"><span style="font-weight: normal;"> editions do not support then either.</span></span><br />
</div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com0tag:blogger.com,1999:blog-6797839624244344630.post-23304723308516787162009-12-08T14:53:00.001+02:002011-09-23T13:47:37.394+03:00Видео лекция по AspectJ<div style="margin-bottom: 0cm;"><b>Аспектно-ориентированное программирование</b> (АОП) — парадигма программирования, основанная на идее разделения функциональности для улучшения разбиения программы на модули. Основная идея сводится к выделению сквозной функциональности, разбросанной между существующими модулями программы (классами, функциями), в отдельные аспекты, которые потом можно повторно использовать. Многие контейнеры, среди которых и <a href="http://www.springsource.org/" target="_blank">Spring Framework</a>, содержат в своем ядре АОП и используют его, а некоторые даже предоставляют свою реализацию (<a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop.html" target="_blank">Spring AOP</a>, <a href="http://www.jboss.org/jbossaop/" target="_blank">JBoss AOP</a>).<br />
</div><br />
<div style="margin-bottom: 0cm;">АОП мне понравилось своим нестандартным подходом. Всем известная единица модульности в ООП — это класс. Некий набор классов, где каждый выполняет совсем разные функции, может содержать определенную сквозную функциональность, не имеющую отношение к логике самих классов. Это может быть управление транзакциями, кеширование данных, ведение логов, уведомление пользователя и т. д. Как сделать так, чтобы функциональность не дублировалась? Можно воспользоваться самим ООП, применить наследование или агрегацию, но тогда классы все равно будут зависеть от других. Можно применить различные <a href="http://ru.wikipedia.org/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" target="_blank">шаблоны проектирования</a> — <a href="http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8" target="_blank">внедрение зависимостей</a>, например, но тогда приложение становится зависимым от сторонней библиотеки, применение которой не всегда может быть оправдано. Шаблоны проектирования помогают решить большинство проблем, связанных с проектированием приложения, но что, если сам шаблон содержит, либо приводит к появлению, сквозной функциональности (например, шаблон <a href="http://ru.wikipedia.org/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BD%D0%B0%D0%B1%D0%BB%D1%8E%D0%B4%D0%B0%D1%82%D0%B5%D0%BB%D1%8C" target="_blank">Наблюдатель</a>, где дублируется логика управления наблюдателями)? <br />
</div><br />
<div style="margin-bottom: 0cm;">Решением описанных проблем может быть, и на самом деле есть, применение АОП. Сквозная функциональность выносится в отдельный модуль, называемый <b>аспектом</b><span style="font-weight: normal;"> (</span><i><span style="font-weight: normal;">aspect</span></i><span style="font-weight: normal;">)</span>. В нем также определяется с помощью <b>точек соединения</b><span style="font-weight: normal;"> (</span><i><span style="font-weight: normal;">joint-points</span></i><span style="font-weight: normal;">)</span>, где, в каких местах, и при каких условиях будет применяться данная функциональность, называемая <b>советом</b><span style="font-weight: normal;"> (</span><i><span style="font-weight: normal;">advice</span></i><span style="font-weight: normal;">)</span>. Советы могут привязываться к точкам соединения либо во время компилирования программы, либо во время загрузки программы, либо даже во время работы программы. Разные библиотеки реализации АОП предоставляют разные возможности.<br />
</div><br />
<div style="margin-bottom: 0cm;">АОП реализовано во <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming#Implementations" target="_blank">многих языках программирования</a>. Для Java одной из успешных реализаций является <a href="http://eclipse.org/aspectj/" target="_blank">AspectJ</a>. Для работы с ней в среде <a href="http://www.eclipse.org/">Eclipse</a> отлично подойдет плагин <a href="http://www.eclipse.org/ajdt/" target="_blank">AJDT</a>. Документации по AspectJ и вообще по АОП можно найти много, но мне больше всего нравятся два источника. Первый — это <a href="http://eclipse.org/aspectj/doc/released/adk15notebook/index.html">AspectJ 5 Developer's Notebook</a>. Он же содержится сразу в помощи (F1) к плагину AJDT. Второй источник — это цикл статей<span style="font-style: normal;"> <a href="mailto:AOP@Work">AOP@Work</a> </span>от IBM. После того, как познакомитесь с АОП, рекомендую прочитать статью <a href="https://www.ibm.com/developerworks/ru/library/j-aopwork15/" target="_blank">AOP@Work: Мифы и реальности АОП</a>, где развенчиваются некоторые мифы, связанные с использованием АОП, и где содержатся дополнительные ссылки для изучения АОП.<br />
</div><br />
<div style="margin-bottom: 0cm;">Идея рассказать студентам про АОП у меня возникла тогда, когда я решил к курсовому проекту по предмету «Технологии проектирования программных систем» добавить контейнер <a href="http://www.springsource.org/" target="_blank">Spring Framework</a>, чтобы он создавал все необходимые сервисы, связывал их между собой, а также управлял транзакциями и работой с базой данных. Управление транзакциями происходит декларативно с помощью Java аннотаций над методами или классами. А вот непосредственно код, связанный с транзакциями, находится в аспектах, которые подключаются к проекту. На лекции я старался объяснить, что нам дает использование АОП, а также показать основные способы применения AspectJ.<br />
</div><br />
<center><br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/X_QJMKEgJBk" frameborder="0" allowfullscreen></iframe>
</center><br />
<br />
<b>Update</b>: Ниже выкладываю слайды лекции, чтобы Вы их смогли скачать и использовать в своей практике. Для этого нажмите меню в правом нижнем углу, потом нажмите на название презентации слева почти снизу. В новом окне откроется презентация, где ее можно будет скачать.<br />
<br />
<div style="text-align: center;"><iframe src="http://docs.google.com/present/embed?id=dft4kq9d_2977ghw2x893&interval=5&size=m" frameborder="0" width="555" height="451"></iframe><br />
</div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com5tag:blogger.com,1999:blog-6797839624244344630.post-70889991241564916782009-12-04T12:14:00.002+02:002009-12-04T12:24:21.644+02:00Java Swing application to access Blogger<div style="margin-top: 0pt;">This small and very simple application allows you to connect to the Blogger server, see all you blogs, read posts, create new posts and edit them. The use of Java language was determined by the need of running this application on different operating systems. Swing was used for GUI programming because of its simplicity (and one more reason, described below). The name of the application is <a href="http://code.google.com/p/jdesktopblogger" target="_blank">JDesktopBlogger</a>.<br />
</div><br />
<div style="margin-top: 0pt;">After I started to use Blogger I searched for some desktop application to use with it. I've tried to use different open sources projects but none of them fit my needs. Then I thought: why not writing something on your own? Interesting enough, but some big changes came to my life at that time - I've switch my job and moved to another city. At the new job because of some reasons I couldn't start working at the project right away. I had couple of weeks to... do some self education :) I found out that the new project will be dealing with Swing. So I thought - why not create a blogging application? I've incited my friend to help me. We both were waiting for a project to start and while waiting we created this blogging application.<br />
<br />
The application is very simple. The used technologies are limited to <a href="http://java.sun.com/docs/books/tutorial/uiswing/" target="_blank">Swing</a> for GUI, <a href="https://jaxb.dev.java.net/" target="_blank">JAXB</a> for saving account's file, Google's <a href="http://code.google.com/apis/gdata/" target="_blank">Gdata</a> BloggerService for accessing Blogger.<br />
<br />
At the time of writing this post the application is at pre-beta state. :) The features are not very rich, but include the following:<br />
<ul><li>managing of several blogger accounts (includes creating, editing, deleting); <br />
</li>
<li>getting list of all blogs within account;</li>
<li>managing list of all posts within blog (includes creating, editing or deleting posts);</li>
<li>ability to create draft post. </li>
</ul>That's about it :) Not much, but we had to start with something. However, I do have some plans for this application and if time permits we'll add the following:<br />
<ul><li>simple formatting options for post (right now only plain text is supported); </li>
<li>caching of posts and blogs;</li>
<li> saving drafts on local machine; </li>
<li>support of other blogging services by adding plug-in functionality. </li>
</ul><br />
And now the main revelation:<b> This post was written from the created application</b>! :) It's like a proof of its work. <span style="font-size: x-small;">Well, yes, the formatting of links and lists was later edited in the web, but that is the primary to-do for me :)</span><br />
</div>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com2tag:blogger.com,1999:blog-6797839624244344630.post-75426373099632278332009-11-19T11:30:00.003+02:002011-09-23T13:51:18.377+03:00Видео лекции по JavaServer FacesJavaServer Faces — это технология создания веб-приложений, на основе визуальных компонент. Она является одним из стандартов среди технологий J2EE. Главной отличительной особенностью от других существующих технологий построения веб-приложений на языке Java является то, что в JSF все строится на так называемых визуальных компонентах, которые принимают вводимые данные от пользователя, передавая их в код приложения, а также выводят данные приложения в определенной форме. На самом деле JSF — это больше, чем набор компонент и API для управления ими. <br />
<br />
Во-первых, JSF — это спецификация. На данный момент активно дорабатывается версия 2.0 и, если <a href="http://ru.wikipedia.org/wiki/JavaServer_Faces#.D0.92.D0.B5.D1.80.D1.81.D0.B8.D0.B8_JSF" target="_blank">я правильно все понял</a>, то уже в J2EE 6 она появится. До этой версии стандартной была версия 1.2, которую использовать было сложно без применения дополнительных библиотек, таких как <a href="https://facelets.dev.java.net/" target="_blank">Facelets</a>, <a href="http://ocpsoft.com/prettyfaces/" target="_blank">PrettyFaces</a>, <a href="http://www.jboss.org/richfaces" target="_blank">RichFaces</a> или другие <a href="http://en.wikipedia.org/wiki/JavaServer_Faces#Ajax-enabled_JSF_components_and_frameworks" target="_blank">AJAX библиотеки</a>. Популярной реализацией JSF спецификации является <a href="https://javaserverfaces.dev.java.net/" target="_blank">Project Mojarra</a>. Также существует реализация от Apache, которая называется <a href="http://myfaces.apache.org/" target="_blank">MyFaces</a>.<br />
<br />
Во-вторых, JSF — это полноценный фреймворк, на базе которого можно создавать веб-приложения. Кроме визуальных компонент, существует настраиваемая система навигации между страницами, контейнер бинов (managed beans с инжекцией зависимостей), обработка событий, поддержка <a href="http://en.wikipedia.org/wiki/Unified_Expression_Language" target="_blank">EL-языка</a>, управление состояниями компонент и приложения. И, наверное, не менее важное то, что JSF позволяет изменять и расширять свою функциональность, имея стандартизированный API.<br />
<br />
JSF я начал изучать сам в далеком 2007 года. Я открыл обычный <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/" target="_blank">J2EE туториал</a> и внимательно перечитал раздел, связанный с JSF. Я считаю, что невозможно выучить какую-либо технологию, не создав чего-либо с ее помощью. Поэтому, я создал небольшое серверное приложение <a href="http://sourceforge.net/projects/gtalkwap/" target="_blank">GTalkWap</a>, которое позволяло заходить на веб-странички с помощью мобильного телефона с поддержкой <a href="http://ru.wikipedia.org/wiki/Wireless_Application_Protocol" target="_blank">WAP</a> и общаться в сети <a href="http://www.google.ru/talk/intl/ru/about.html" target="_blank">GoogleTalk</a>. У меня тогда был очень слабенький мобильный телефон, Java-приложения на нем не запускались, и поэтому общение таким образом меня очень даже радовало. Запустив это приложение на университетском сервере, я им активно пользовался.<br />
<br />
Позже я узнал про существование замечательной технологии <a href="https://facelets.dev.java.net/" target="_blank">Facelets</a>, которая позволила избавиться от использования JSP страниц, а отображение определять в XHTML. Также она позволила использовать шаблоны страниц, которые мне понравились больше, чем те, что были тогда в библиотеке <a href="http://tiles.apache.org/" target="_blank">Tiles</a> от Apache. С самого начала изучения JSF я знал про существование различных библиотек визуальных компонент. Но как только я начал использовать <a href="http://www.jboss.org/richfaces" target="_blank">RichFaces</a> от JBoss, JSF завоевал мое сердце.<br />
<br />
Рассказывая студентам на лекциях о JSF, я старался покрыть как можно больше материала, не вдаваясь в сложные технические подробности. Сравнивать им было не с чем, так как до этого они знали только JSP, поэтому JSF для них был новой технологией. И чтобы не отбить интерес, я заострял внимание на основных фишках, которые упрощали создание веб-приложений, оставляя детали на самостоятельное изучение. Также отдельно я останавливался на интеграции <a href="http://www.springsource.org/" target="_blank">Spring</a> и JSF, так как весь проект был построен на основе Spring. Специально для студентов я создал приложение-пример <a href="http://kurs.stu.cn.ua/projects/exampletpps" target="_blank">ExampleTPPS</a>, в котором отразил использование таких технологий, как Spring, JPA, Hibernate, AspectJ, JSF, Facelets, RichFaces, Log4J, Ant, JUnit.<br />
<br />
Кстати, на счет самостоятельного изучения JSF, то могу порекомендовать вот <a href="http://www.ibm.com/developerworks/ru/edu/j-jsf1/section1.html" target="_blank">этот небольшой туториал</a> на русском языке от IBM, а также книгу <a href="http://books.google.com/books?id=8WIS2X0HqiEC&dq=Facelets+Essentials:+Guide+to+JavaServer+Faces+View+Definition+Framework&printsec=frontcover&source=bl&ots=KU7gk-MXYi&sig=k9__tE_X4yYPqAq_YATGbYvB86g&hl=en&ei=qg0FS7-qA4LWmQOsw6HHCg&sa=X&oi=book_result&ct=result&resnum=4&ved=0CBUQ6AEwAw#v=onepage&q=&f=false" target="_blank">Facelets Essentials: Guide to JavaServer Faces View Definition Framework</a> (попробовать скачать можно <a href="http://cs.stu.cn.ua/%7Eyet/books/apress.facelets.essentials.may.2008.pdf" target="_blank">тут</a>), ну и, конечно, собственные лекции, которые идут ниже. :)<br />
<br />
<iframe width="560" height="315" src="http://www.youtube.com/embed/YlBkPYNj1U0" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/QxNCqGAVy7Q" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/zX7WzGfM0rM" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/reudKF6gtUY" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/uqvWaOO6v4w" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/9vVqebGYhyU" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/zt1-anHsR40" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<b>Update</b>: Ниже выкладываю ссылки на слайды лекций, чтобы Вы их смогли скачать и использовать в своей практике.<br />
<a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_3256ddj3b2dg">Лекция 14</a>, <a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_3391w8s2rkdj">Лекция 15</a>, <a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_3335f55qsxfc">Лекция 16</a>, <a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_3443f6qfdrhm">Лекция 17</a>, <a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_35065tjzzzf8">Лекция 18</a>, <a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_3370c35kc4zh">Лекция 19</a>, <a target="_blank" href="http://docs.google.com/present/view?id=dft4kq9d_3381cj5gbh4q">Лекция 20</a>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com14tag:blogger.com,1999:blog-6797839624244344630.post-34661641097867826652009-11-11T23:41:00.006+02:002011-09-23T13:25:19.793+03:00Видео лекция по Spring FrameworkSpring Framework - популярная библиотека среди многих Java разработчиков, которая является легковесным контейнером и содержит богатый набор вспомагательных классов для поддержки инфраструктуры как веб-приложений, так и настольных. Spring позволяет применять паттерн "<a href="http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8">внедрения зависимостей</a>" (<a href="http://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a>) для организации взаимодействия компонент системы, выступая для них контейнером. Вместе с богатым набором классов для упрощения доступа к данным, организации веб представления, защиты приложения и взаимодействия со многими популярными библиотеками Spring может быть хорошей альтернативой использованию EJB, особенно там, где не требуется наличие EJB-контейнера и всей его инфрастуктуры. <br />
<br />
Для подробной информации об использовании Spring могу порекомендовать книгу <a href="http://www.manning.com/walls3/">Spring in Action, Second Edition</a> от Manning (если хотите скачать, посмотрите <a href="http://mirknig.com/knigi/web/1181230847-sbornik-manning.html">тут</a>, ну или поищите в гугле, найти книгу не сложно).<br />
<br />
Так вот, читая эту книгу, мне очень понравилось изложение материала. Сначала рассказывается о "внедрении контроля" (другие варианты названия - <i>инжекция зависимостей</i>, <i>инверсия контроля</i>). Причем, все объясняется на простеньком примере. Потом рассматривается уже разработка сложного веб приложения и объясняются все другие возможности Spring-а.<br />
<br />
Рассказ о "внедрении контроля" (мне, все же, больше нравится вариант "инжекция зависимостей", так как это дословный перевод с английского) особенно понравился. Там рассказывается о разработке и тестировании приложения, которое обеспечивает походы <a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D1%80%D0%BE%D0%BB%D1%8C_%D0%90%D1%80%D1%82%D1%83%D1%80">Короля Артура</a> для поиска <a href="http://ru.wikipedia.org/wiki/%D0%93%D1%80%D0%B0%D0%B0%D0%BB%D1%8C">Священного Грааля</a>.<br />
<br />
Рассказывая лекцию по Spring, я знал, что всю информацию уложить в 80 минут у меня не получится. Поэтому я постарался остановиться на самом важном аспекте - инжекция зависимостей. А вместо походов Короля Артура я выбрал то, что ближе для Украины - походы казацкого гетмана. Вместе с этой информацией, я также кратко объясняю и другие аспекты Spring, а, например, про взаимодействие его с JPA я рассказываю в <a href="http://yuriytkach.blogspot.com/2009/11/java-persistence-api-jpa.html">отдельных лекциях</a>, посвященных огранизации доступа к базе данных.<br />
<br />
<div style="text-align: center;">
<iframe width="500" height="375" src="http://www.youtube.com/embed/g95iuj-vWtU" frameborder="0" allowfullscreen></iframe>
</div>
<br />
<b>Update</b>: Ниже выкладываю слайды лекции, чтобы Вы их смогли скачать и использовать в своей практике. Для этого нажмите меню в правом нижнем углу, потом нажмите на название презентации слева почти снизу. В новом окне откроется презентация, где ее можно будет скачать.<br />
<br />
<div style="text-align: center;"><iframe src="http://docs.google.com/present/embed?id=dft4kq9d_2943w4cn85hf&interval=5&size=m" frameborder="0" width="555" height="451"></iframe><br />
</div><br />
Кстати, в <a href="http://googletesting.blogspot.com/">блоге гугла</a>, посвященному тестированию, есть <a href="http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html">статья</a>, где написаны их советы по написанию хорошо тестируемого кода. Более подробно все эти рекомендации представлены в этом <a href="http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf">PDF-файле</a>. Много в чем они сводятся к тому, что необходимо использовать внедрение контроля, чтобы свести зависимости между классами к минимуму. Так что, "внедрение контроля" (или инжекция зависимостей) - это очень и очень полезная штука. :)Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com1tag:blogger.com,1999:blog-6797839624244344630.post-54297203025968143242009-11-11T20:10:00.005+02:002011-09-23T13:22:29.695+03:00Видео лекции по Java Persistence API (JPA)Работая преподавателем в <a href="http://stu.cn.ua/">Черниговском государственном технологическом университете</a> на кафедре <a href="http://cs.stu.cn.ua/">Информационных и компьютерных систем</a>, я читал курс лекций по предмету ТППС (Технологии проектирования программных систем). В основном я старался делать упор на проектирование систем, рассказывая про разные шаблоны, подходы, многослойную архитектуру и т.п. Материал свой я основывал на замечательной книге Мартина Фаулера "<a href="http://www.ozon.ru/context/detail/id/1616782/">Архитектура корпоративных программных приложений</a>".<br />
<br />
Однако, без рассказа о технологиях, которые применяются для создания систем уровня предприятия, этот курс был бы не таким интересным. Весь курс основывался на технологиях J2EE и связанными с ними, и поэтому включал в себя такие темы как Spring, AOP, JPA, Hibernate, JSF.<br />
<br />
В последний год своего преподавания я случайно додумался записывать лекции на видео, используя способ, описанный в <a href="http://yuriytkach.blogspot.com/2009/11/blog-post.html">предыдущем посте</a>.<br />
<br />
В этом посте я решил выложить лекции, где я рассказываю про технологию JPA и использование Hibernate, в качестве ее реализации. Попутно, вместе с JPA, я рассказываю про разные шаблоны реализации слоя доступа к данным, шаблоны отображеня наследования объектов на реляционные таблицы базы данных, и есть интересные лекции про транзакции, DAO и использование Spring+JPA.<br />
<br />
Все лекции, собранные в одном месте, чтобы легче было их искать и следовать по ним :)<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/h7K1WXQ550s" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/r8SlsJjmm8o" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/fKO6kbTUEuo" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/xmdrf-Vu9Wo" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/WEpUpv7b09s" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<iframe width="500" height="375" src="http://www.youtube.com/embed/4PKZRQAtf38" frameborder="0" allowfullscreen></iframe>
<br />
<br />
<b>Update</b>: Ниже выкладываю ссылки на слайды лекций, чтобы Вы их смогли скачать и использовать в своей практике.<br />
<a href="http://docs.google.com/present/view?id=dft4kq9d_2989gm397bcr" target="_blank">Лекция 8</a>, <a href="http://docs.google.com/present/view?id=dft4kq9d_3052fp5nwtfz" target="_blank">Лекция 9</a>, <a href="http://docs.google.com/present/view?id=dft4kq9d_3113dqzhvcgt" target="_blank">Лекция 10</a>, <a href="http://docs.google.com/present/view?id=dft4kq9d_3168hk4drkhb" target="_blank">Лекция 11</a>, <a href="http://docs.google.com/present/view?id=dft4kq9d_3190hj79rgg5" target="_blank">Лекция 12</a>, <a href="http://docs.google.com/present/view?id=dft4kq9d_3233dws46wcp" target="_blank">Лекция 13</a>Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com5tag:blogger.com,1999:blog-6797839624244344630.post-74797758491960484072009-11-09T00:21:00.004+02:002009-11-11T20:32:06.337+02:00Видео лекции. Работающая реализацияПреподавая в <a href="http://stu.cn.ua/">университете</a> на <a href="http://cs.stu.cn.ua/">кафедре Информационных и компьютерных систем</a> у меня давно возникала идея создания видео материалов для помощи студентам. Воплощал я идею по-разному. Сначала я просто записывал экран моего компьютера, где показывал как делать ту или иную лабораторную работу. После добавил пояснения к видео и начал не только туториалы по лабораторным делать, а и небольшие теоретические описания. Любил баловаться, <a href="http://video.google.com/videoplay?docid=1472197872902491630&ei=Rj33SumoL4mO2wKG8a2LCw&q=annotation+transaction+aspect#">накладывая музыкальное сопровождение к таким видео</a>. Такие видео пользовались (а может и до сих пор пользуются) популярностью у студентов, так как они могли повторять шаги за видео, слушать пояснения и сразу выполнить работу. Получалось практически виртуальное занятие.<br />
<br />
Какие же инструменты я использовал для этого? <br />
<br />
Сначала я пользовался операционной системой Windows и программой <a href="http://www.techsmith.com/">SnagIt</a>. Неплохая программка, много чего умеет. Но требовала дополнительной обработки видео, причем много. Она генерировала ооочень большой видео файл. Как я понял, она записывала полные кадры, что естественно и сказывалось на размере выходного файла. Не знаю, может сейчас она уже получше работает :) К тому же программа притормаживала тогда еще на моей машине, так что вскоре я разочаровался в ней.<br />
<br />
Дальше я нашел и попробовал такую программу, как <a href="http://www.jingproject.com/">Jing</a>. Что мне понравилось, так это то, что она сразу генерировала swf-файл, который я потом без проблем мог вставить на веб-страницу и все. Плеер был, как бы, интегрирован в тот файл. Все замечательно, если бы не некоторые ограничения. Бесплатная версия программы позволяла записывать только 5 минут видео. К тому же редактирование видео исключалось, так как для этого необходимо было парсить swf-файл, вытягивать оттуда видео, потом как-то его назад туда загонять. В общем, <a href="http://cs.stu.cn.ua/%7Eyet/index.php?v=jtap">несколько видео туториалов</a> я сделал, но на этом все закончилось.<br />
<br />
Потом я как-то, сам того не замечая :), перешел на использование операционной системы <a href="http://www.ubuntu.com/">Ubuntu</a>. Как только я начал активно использовать различные OpenSource программы, я поискал и нашел замечательную программу <a href="http://www.kdenlive.org/">Kdenlive</a>, которая для записи рабочего стола использовала утилиту <a href="http://recordmydesktop.sourceforge.net/about.php">recordmydesktop</a> (которая устанавливается вместе с kdenlive). Скорость работы просто супер. Ни капельки не тормозила и не мешала работать основным программам. Я даже пару раз забывал, что у меня включена съемка экрана :) Позволяет писать как полные кадры, так и только фиксировать изменения, благодаря чему размер видео файла получается достаточно небольшим. Кроме того программа содержит все необходимые инструменты для редактирования видео и очень богатый набор различных аудио и видео эффектов. Так что на данный момент - только плюсы!<br />
<br />
Туториалы туториалами, но мне захотелось большего!<br />
<br />
Я подумал: а почему бы не записывать собственные лекции? У ребят из MIT на YouTube целый <a href="http://www.youtube.com/user/MIT">образовательный канал свой</a>. Причем не только у них, а и у многих других университетов. Чем мы хуже? :) Ведь можно записывать не только звук, а и видео, да еще и добавлять в видео сразу слайды лекции. Учитывая, что доску и мел я практически не использовал, так как всегда был проектор и слайды, то на видео можно было только снимать собственно меня, а потом еще наложить картинки слайдов и все.<br />
Реализовать эту идею мне удалось достаточно просто с минимальными затратами.<br />
<br />
Итак, что же я использовал.<br />
<ul><li><b>Железо</b>: использовался мой собственный ноутбук со встроенной веб-камерой. Да, всего 1.3 мега-пикселя, разрешение 640х480, но поверьте мне - для <a href="http://www.youtube.com/ytkach#p/c/3174697F6ADAD861/0/PlORw0bTJnY">видео лекции</a> на YouTube этого достаточно. Микрофон я брал внешний, так как встроенный был уж очень слаб. Внешний был тоже не супер-пупер, обычный компьютерный микрофон примерно за $7.<br />
</li>
<li>Как вы уже можете догадаться, все операции, включая съемку и обработку видео, я выполнял в <b>операционной системе</b> <b><a href="http://www.ubuntu.com/">Ubuntu</a></b>.</li>
<li><b>Софт 1</b>: Съемку я делал простенькой программкой <b><a href="http://projects.gnome.org/cheese/">Cheese Webcam Booth</a></b>. Наверное, проще этой программы ничего и не найдешь. Ну а больше мне и не надо было. Она снимала, и я получал видео файл со звуком :)</li>
<li><b>Софт 2</b>: Полная обработка видео выполнялась в уже упомянутой <b><a href="http://www.kdenlive.org/">Kdenlivе</a></b>. Я вырезал ненужные фрагменты из видео, накладывал картинки слайдов лекций, добавлял различные эффекты, и (!) сразу сохранял видео в формате, <a href="http://www.google.com/support/youtube/bin/answer.py?answer=132460&topic=16612&hl=en-US">наиболее приемлемом для YouTube</a> (один из профайлов экспорта в программе). </li>
<li><b>Софт 3</b>: Обработка звука производилась в программе <a href="http://audacity.sourceforge.net/"><b>Audacity</b></a>. Дешевенький микрофончик давал очень низкое качество звука. Основная проблема - это шумы. Но благодаря это программе, я удалял практически все шумы, увеличивал уровень сигнала, и подправлял эквалайзером звук. Несложные махинации - и на выходе я получаю приемлемый звук (не супер-пупер, но слушается отлично) в отдельном mp3-файле.</li>
<li><b>Софт 4</b>: Склеивание звука с видео и разрезание видео на части для YouTube (туда можно загружать файлы <a href="http://www.google.com/support/youtube/bin/answer.py?hl=en&answer=55743">не более 10 минут длительностью</a>). Эти две операции выполнялись в программе <a href="http://fixounet.free.fr/avidemux/"><b>Avidemux</b></a>. Это тоже очень интересная и богатая функционалом программа. Но в данном случае никакой дополнительно обработки видео и аудио мне не нужно было. Эта программа позволяет двумя щелчками мышки заменить основной аудио-файл для видео, а потом сохранить видео по частям.</li>
</ul>Стоит отметить <i>затраты</i> такого решения для обработки лекции длительностью в 80 минут:<br />
<ul><li>Стоимость софта - 0.0 любой валюты. OpenSource тут явно рулит.<br />
</li>
<li>Стоимость железа - $7 за внешний микрофон. Ноутбук давайте считать не будем, так как он покупался совсем для других целей, а не для записи видео лекций.</li>
<li>Время на обработку - примерно 2 часа на редактирование видео и звука и еще около 1 часа на все операции сохранения. Итого примерно 3 часа.</li>
<li>Время на закачку в YouTube - не будем хвастаться скоростью нашего интернета (или наоборот жаловаться на скорость) :)</li>
</ul>Лицезреть результат видео лекций по курсу ТППС вы можете, например, <a href="http://www.youtube.com/ytkach">на моем канале YouTube</a>, ну или список всех лекций вместе с презентациями на <a href="http://cs.stu.cn.ua/blogs/thematic.html?id=145">блоге сайта кафедры</a>. <br />
<br />
Скажу еще, что в YouTube можно <a href="http://www.google.com/support/youtube/bin/answer.py?hl=en&answer=57792">создавать плейлисты</a>. Вы загружаете туда несколько видео, потом добавляете их все в один плейлист, и уже встраиваете себе на страницу этот плейлист. Когда пользователь смотрит видео, то они для него автоматически переключаются сами. :)<br />
<br />
<br />
<b>P. S.</b> Один из студентов прислал мне ссылку на пост <a href="http://habrahabr.ru/blogs/edu_2_0/74456/">Видео-трансляция лекций. Реализация</a>. Человек, написавший тот пост, задался вопросом, как бы ему реализовать запись и потом трансляцию лекций. На момент написания этого поста мной, я так понял, что он еще не решил, как же он это будет делать.<br />
<br />
Очень понравилось читать комментарии, где многие предлагали удивительные по своей <strike>стоимости</strike> красоте решения. Много кто <strike>умничал</strike> высказывал авторитетно про необходимое качество звука и видео. Конечно, при наличии денег, можно и камеру хорошую взять, и радио микрофон повесить на лектора, и компьютер мощный для обработки видео, и профессионала для настройки всего этого и редактирования. Все это можно, но боюсь, что пока невозможно в нашей стране.<br />
<br />
Но если есть желание, то все можно реализовать, используя, так сказать, подручные средства. Это во-первых дешево, а во-вторых работает. Доказано <strike>занусси</strike> мной :)Yuriyhttp://www.blogger.com/profile/12003943897147040263noreply@blogger.com7