Как стать автором
Обновить

Комментарии 50

НЛО прилетело и опубликовало эту надпись здесь
Ну кстати, да — реализовать можно на любом языке:)
Как думаете, стоит ли снабдить материал ссылками на пакеты и библиотеки, знание которых понадобиться для реализации того или иного пункта?

Конечно стоит!
Сейчас что-нибудь придумаем:))
не стоит. Потому как не знание либ и пакетов приведёт к запоминанию всего, что не известно. Плюс к этому работа с информацией, знание что и где лежит и т.д. Разве это не может быть полезным? А если снабдите материал, то тут вы облегчаете людям задачу.

Как говорила моя бабушка: «Если решать сложные уравнения, простые — покажутся орешками...»
«Если научишься решать...»
Как, парсер регулярных выражений писать не надо? Либами не интересно…
а для прям начинающих начинающих можно ?:)))
Прям с первой задачи — можно:) На самом деле если все делать последовательно и увеличивать сложность шаг за шагом, то все будет достаточно просто:))
Уважаемый DbLogs, расскажите, откуда у вас такой альтруизм?
Придумываете задачки и даже готовы их проверять, лично я бы так не смог. Может вы в Sun работаете на полставки? Или ищите молодых талантливых (или не очень талантливых) программистов?

p.s. Спасибо Вам за эту и прошлую статью, думаю многим будет полезно. ИМХО, сильный поступок.
Все банально и просто:) Я просто стараюсь структурировать имеющуюся у меня информацию по Java.
А вообще, вы правы, есть у меня еще и несколько корыстная подоплёка: есть у меня один ну очень-очень интересный проект (нет не тот, о котором я пишу иногда в своем блоге) и где-то там я надеюсь, что может быть смогу найти здесь людей, которых смогу обучить Java'е, а они в свою очередь смогут чем-нибудь помочь сообществу развивающему тот проект:)
Что скажите про мой код?
Тестированием особо не занимался. :(
Работает на «ls / | java grep.Main \\d+ oo bin» и на «ls / | java grep.Main \\w+», вроде как. :)

package grep;

import java.util.Scanner;

public class Main
{
// точка входа в программу
public static void main(String[] args)
{
//проверяем кол-во аргументов
if (args.length == 0)
{
System.err.print("Invalid parametrs for program. ");
System.err.println("Program must have one parametr.");
return;
}
Scanner in = new Scanner(System.in);
//начинаем разбор по строчкам
while (in.hasNext())
{
String str = in.nextLine();
Scanner s = new Scanner(str);
for (String iterStr: args)
if ((str.toLowerCase().indexOf(iterStr.toLowerCase()) != -1) ||
(s.findInLine(iterStr) != null))
{
System.out.println(str);
break;
}
s.close();
}
in.close();
}
}
Зачет:) Хотя комментарии рекомендую обычно писать на русском: меньше проблем будет с разными компиляторами:)
программа 2. Думаю, код ясен.
package sort;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Scanner;

public class Main
{
//вспомогательный класс, реализующий удобный нам формат строк
static private class MyString implements Comparable {
private String interString;
private int sortIndex = -1;
public MyString(String str, int wordNum)
{
this.interString = str;
this.sortIndex = wordNum;
}
public String getStr()
{
return interString;
}

public int compareTo(MyString arg0)
{
//сортировка без учёта регистра
//return str.toLowerCase().compareTo(arg0.getStr().toLowerCase());
//сортировка по длинне (будет выполняться елси параметр не задан)
if (sortIndex == -1) return interString.length() - arg0.getStr().length();
//сортировка по sortIndex`овому слову в строке
String str1 = null, str2 = null;
try
{
str1 = interString.split(" ")[sortIndex];
}
catch (Exception e)
{
//если нет нужного слова в 1ой строке, то считаем что первое слово меньше 2ого.
return -1;
}
try
{
str2 = arg0.getStr().split(" ")[sortIndex];
}
catch (Exception e)
{
//если нет нужного слова во 2ой строке, то считаем что 2ое слово меньше 1ого
return 1;
}
//здесь сравниваем корректно
return str1.compareTo(str2);
}
};
// точка входа в программу
public static void main(String[] args)
{
//устанавливаем номер слова в строке для сортировки (если не указал, то -1)
int sortIndex = -1;
//проверяем кол-во аргументов
if (args.length != 0) sortIndex = Integer.valueOf(args[0]);
Scanner in = new Scanner(System.in);
ArrayListsortList = new ArrayList();
//начинаем разбор по строчкам, и заполнение объекта контейнера
while (in.hasNext())
sortList.add(new MyString(in.nextLine(), sortIndex));
Collections.sort(sortList);
//печать на экранчик
Iteratoriter = sortList.iterator();
while (iter.hasNext())
System.out.println(iter.next().getStr());
in.close();
}
}

Да и еще, данный способ работает с юникодом?
Или нужно будет использовать уже производные от Reader (Stringreader например)?
А у меня на этой строке ошибку выдает…
for (String iterStr: args)

C:\grep>javac Main.java
Main.java:21: ';' expected
for (String iterStr: args)
^
Main.java:28: illegal start of expression
}
^
2 errors
Скорее всего не той версией JDK компилите.
Необходимо JDK 1.5 +
Точно :) перенаправил на 1.6 все запахало.

Сразу такой вопрос: а где найти отличия от предыдущих версий? Например для того же for?
Что за проект? Хотя бы какое направление и что напоминает?
Высокопарная презенташка здесь:
interlogy.org/
:)
Спасибо.
Будет занятие на выходные.
В интернете полно онлайновых проверяющих систем, на которых можно учится писать простые программы на той же Java. Например acm.timus.ru (http://acm.timus.ru), TopCoder (http://topcoder.com/tc) и многие другие. Ссылки можно найти на Snarknews (http://snarknews.info). Задачи в основном олимпиадные, но сложность их варьируется от элементарных до мегасложных — каждый найдет для себя что-то интересное.
По собственному опыту скажу, что после года на топкодере у меня очень сильно выросла аккуратность и скорость написания кода, я не говорю уже про скорость мышления.
P.S. Извините, похоже из-за отрицательной кармы ссылки у меня не парсятся :(
Олимпиадные задачи — это особый род онанизма, если посмотреть. По крайней мере там учишься писать быстро, но не факт, что правильно. На недавнем 1/4 ACM ICPC какого только ужаса в коде нашей команды не было. Но за красотой там не уследишь, главное — скорость. Да и задачки, там предложенные, большей частью алгоритмические, здесь же предложены задачи на технику. Технику, более необходимую при работе в реальных проектах. Проверяется умение работать с классами, а в олимпиадных задачах кроме ввода-вывода, контейнеров и длинной арифметики ничего в 99% случаев и не используют. Плюс dirty debug и наплевательское отношение к исключительным ситуациям. Говорю не по наслышке, уже 4 года в олимпиадах. Аккуратность и скорость растут, факт, но зачастую в ущерб правильному планированию кода. Так что эти задачи можно рассматривать как тренировку для ума и ловкости пальцев, а не проверку реальных знаний, которые могут пригодиться в работе.
На топкодере dirty debug не пройдет ;) Впрочем, я забыл сказать, что сочетал его не только с АСМ, но и с работой девелопером в довольно большой аустсорсинговой компанией.
На топкодере оверхед по коду не пройдёт, то есть — может не пройти. 30% вроде. А dirty debug — может, сам пару задач на 500 с грязными хаками сдавал. Зато там очень не радует стиль написания с дефайнами для циклов. Вроде бы для себя оптимизируешь, а читаемость падает. Не думаю, что кто-то такой стиль применяет при реальном кодинге :)
в олимпиадных задачах кроме ввода-вывода, контейнеров и длинной арифметики ничего в 99% случаев и не используют.

Наверное, за четыре года вы не полностью прониклись. Забыли сортировки, геометрию (которую я ненавижу), графы! В общем, много чего забыли. Тем более, что олимпиадные задачки, в первую очередь — разминка для ума. Они неплохо учат оптимизировать как время выполнения, так и используемую память. Очень здорово помогают избавиться от говнокода.
И самое интересное — это ограничение по времени выполнения. Сделал задачку перебором, а она тесты по времени не прошла :)
Самое интересное — это перебор с отсечениями, когда задачка, густо приправленная вазелином, всё-таки проползает TL =)
Ну, положим, в случае Java сортировку можно отнести к контейнерам, так как они теееесно связаны через Java.util.Collections, графы и геометрия — это не более чем структуры данных + алгоритмы на них, я же говорил про то подмножество классов, которого хватает при написании олимпиадных задач на Java. (да, я ещё забыл теорию чисел, которая решается посредством класса «штатный математик команды», сам 4 года в такой роли, хотя сейчас больше кодингом занимаюсь).

Оптимизировать — учат. Но зачастую и отучивают в простых случаях (по типу «ааа, оно и так зайдёт» или «ааа, в память влезем»). Читаемость кода в большинстве случаев достаточно низка — поскольку каждую задачу увидят максимум 3 человека (зачастую — и того меньше, нас сейчас, например, двое в команде, в очередной раз штурмуем Всесибирскую олимпиаду).
в очередной раз штурмуем Всесибирскую олимпиаду).

удачи вам ;-)

я же говорил про то подмножество классов, которого хватает при написании олимпиадных задач на Java

Я немного не согласен с вами. Стандартные классы хороши тем, что позволяют быстро писать высокоуровневый код не вдаваясь в реализацию мелочей. Как вы думаете например, sort на Java какой алгоритм использует? Скорее всего, quicksort (хотя я наверняка не знаю). А если задача требует отсортировать подсчётом? Или вообще как-нибудь хитро, чтобы влезть в TL? То же касается задач на графах и многих других задач. Кроме того, Java сильно проигрывает тому же C в скорости работы программы а, например, в том же Timus'e по-моему, нет прибавки к времени для сабмитов на Java. В общем, некоторые программы даже теоретически не могут там пройти.
В общем, для общего развития нужно всем понемногу заниматься, и олимпиадными задачами и про ассемблер представление иметь, никогда не знаешь, где это поможет.
Олимпиадные задачи это целая отдельная тема:) Я их рекомендую использовать сотрудникам именно для воспитания аккуратности — хотя к тому же зачастую приводит написание юнит тесткейсов:)
Спасибо, я как раз Java учу, будет что поделать.
Спасибо, очень интересно.
Пытаюсь сделать на пайтоне.
На самом деле пытаюсь искать подобные задачи, но нахожу очень и очень мало, не знаю на чем практиковаться.
Если какой-нибудь кладезь найдете, то дайте знать, пожалуйста:)
Ух ты! Очень занимательно, уже час угрохал… Спасибо! *ушел учить джаву*
:)Спасибо за топик, полезно.
Автору, может должно быть `cd` вместо `cp`?
Спасибо — я и не заметил:)
Из недавнего (задавали на интервью).

№1: Написать функцию int atoi(String), для парсинга чисел в -7-ичной записи (основание системы счисления — минус семь). Спрашивают можно ли написать функцию format() для этой системы счисления (надо объяснить почему).
№2: Написать класс «синглетон». А потом найти ошибку (все забывают synchronized).
№3: Написать редиректор потока с методом redirect( InputStream sfrom, OutputStream sto ) (внутри надо создать поток и догадаться его закрыть вовремя). Предложить использовать это для управления консольным приложением (читаем out-пишем in по строчкам). Запустить под линь (в их случае правда был AIX) и объяснить почему не работает (кэширование труб в ОС)
№4: Дают двухтердовое приложение, которое хватает дедлок. Предлагают найти проблему.
№5: Дают аппликуху которая выносит яву по нехватке памяти. Делается это путем создания большого графа ссылок. Предлагают объяснить что случилось и «поправить». Проблема как я понял была в том, что gc не успевал прошуршать по всему графу, а аппликуха создавала уже новый.
№6: Есть лог (w3c, например), надо заменить все похожие строчки идущие подряд на одну. Типа 01/01/2001 login bob\n 01/01/2001 login sam \n заменить на 01/01/2001 login **** (x 2). Смотрят на то, как пытаешься сформулировать «похожесть» и как пытаешься ее вычислить.
№7: Дают интерфейс 3-мерного куба (get(x,y,z)/set(x,y,z),sizeX(),sizeY(),sizeZ()). Предлагают сделать реализацию. Потом с ней построить кубик 1Mx1Mx1M, заполнить в нем 2M точек целыми значениями. Затем каждую точку куба заменить на среднее арифметическое точек в округе. Если делаешь трехмерный массив предлагают увеличить сторону куба до 10^10. Хотят увидеть объектное моделирование и аналог two phase commit (чтобы точки расчитанные на i-m шаге НЕ влияли друг на друга).
№8: Просят написать кэширующий калькулятор. Типа ему дают арифметические выражения с переменными и без скобок и (a+b-c*d/e), он должен найти в кэше подвыражения (a+b и c*d/e) и сделать расчет с использованием результатов выражений. Хотят увидеть класс Expression, который умеет парсить выражения, приводить их к нормальному виду и делать хитрые compareTo(), hashCode() и equals() чтобы Map с ним работал.
№9: Просят сделать переменное количество вложенных циклов (дали N-мерный массив каждую точку заполнить суммой ее координат). Хотят увидеть злобный итератор. Стек и рекурсию не принимают.

Мне понравилось — все задачи имеют решения по паре страниц или около того.
это всё вам задавали?
№8 и №3 задавали не мне. Остальное — да. В общей сложности я почти на 2 десятка интервью в тот месяц съездил :-)
Хочу сказать спасибо за эту статью! Она сподвигла меня на некие действия. Во-первых благодаря ней я-таки съездил в магазин и купил книгу «JAVA 2 Тонкости программирования» второй том. Когда бы иначе я до этого дошёл? ))
Взялся за третью задачу. Т.к. первые две для меня не интересны.
Впервые стал разбираться с многопоточностью.
Первые три подзадачи сделал. А вот на четвёртом пункте подзастрял. Пока не могу сообразить как сделать так, чтобы введённое одним пользователем — выводилось сразу у всех. Нужно как-то передавать информацию между потоками. Как это обычно делается? Т.е. чтобы один поток пробуждал все остальные.
Подсказки от вас могут быть? =) Вот реализация первых трёх пунктов. Она немного изменена, т.к. я работал над четвёртым. Запись в файл, к примеру, в первых трёх пунктах не нужна. Пока не пойму потребуется ли она вдальнейшем.

Класс chat

package ru.chat;

import java.io.*;
import java.net.*;

public class chat {
public static void main(String args[]){
try{
int i =1;
ServerSocket s = new ServerSocket(1234);
while (true){
Socket incoming = s.accept();
System.out.println(«Swaping „+i);
Runnable r = new ThreadedChatHandler(incoming);
Thread t = new Thread®;
t.start();
i++;
}
}
catch (IOException e){
e.printStackTrace();
}
}
}

класс ThreadedChatHandler

package ru.chat;

import java.io.*;
import java.net.*;
import java.util.*;

public class ThreadedChatHandler implements Runnable{
public ThreadedChatHandler(Socket i){
incoming = i;
}
public synchronized void run(){
try{
try{
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream,true);
RandomAccessFile fileIn = new RandomAccessFile(“history.txt»,«r»);
fileIn.skipBytes((int)fileIn.length());
out.println(«Hello! Enter BYE to exit.»);
String answer = "";
while (answer != null){
String line = in.nextLine();
FileWriter fileWrite = new FileWriter(«history.txt»,true);
fileWrite.write(«Echo: „+line+“\n»);
fileWrite.close();
answer = fileIn.readLine();
out.println(answer);
if (line.trim().equals(«BYE»)) break;
}
}
catch (FileNotFoundException e){
e.printStackTrace();
}
finally{
incoming.close();
}
return;
}
catch(IOException e){
e.printStackTrace();
}
}
private Socket incoming;
}

класс ChatClient

package ru.chat;

import java.io.*;
import java.net.*;
import java.util.*;

public class ChatClient{
public static void main(String args[]){
try{
Socket s = new Socket(«localhost»,1234);
try{
InputStream inStream = s.getInputStream();
OutputStream outStream = s.getOutputStream();
Scanner in = new Scanner(inStream);
Scanner userin = new Scanner(System.in);
PrintWriter out = new PrintWriter(outStream,true);
while(in.hasNextLine()){
String line = in.nextLine();
System.out.println(line);
if (!line.equals(«Echo: BYE»)) out.println(userin.nextLine());
}
}
finally{
s.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
Такое ощущение, что вы пришли в джаву с С. Это так?:) Дело в том, что в С подход к потокам значительно отличается от подхода в Java. Первое что Вам следует уяснить для решения 4 пункта так это то, что поток в джаве такой же объект как и все остальные: т.е. его можно добавлять в коллекции, можно определять свои новые методы и т.д. и т.п.
Для четвертого пункта Вам НЕ нужно складировать все сообщения в файл. Для этого достаточно:
1) Складировать все потоки в коллекцию
2) Реализовать свой вариант Thread, который бы имел метод например sendMessage
3) При приеме сообщения проходимся по всем элементам коллекции из п.1 и вызываем sendMessage
Как домашнее задание по 4 пункту: необходимо так же чистить коллекцию от потоков, которые закончили свою работу — т.е. пользователь отключился.
Так же в качестве коллекции можно использовать такую вещь в Java как ThreadGroup:)
Если будут вопросы — пишите! Можно и в личку;)
Большое спасибо за пост. На самом деле очень полезно изучать что то новое на реальных проектах, а так как не всегда оное получается, очень помогают такие задачки.

Еще раз спасибо. С нетерпением жду продолжения.

Может чем то можно помочь? Чтоб продолжение вышло скорее?
Помочь можно идеями:) Например какие дальнейшие направления интересны?
К примеру я могу еще выложить «задачник» в том же стиле по сервлетам, JSP + EJB. А так же по Jboss Seam. Но мне кажется, что тот кто разобрался с Java запросто может изучить и эти технологии…
Разобраться то можно во всем наверное, но если у тебя под рукой хорошие инструменты («задачники», справочники и иже с ними), то разбираться легче.

JSP + EJB — это супер. Хотелось бы. Можно еще добавить темы по фреймворкам, для чего они, с чем их едят и тд. Наверное начинающему (мне например) было бы приятно почитать о том где (ну в основном что ли) используется Java, и почему именно она, и решить пару мини-задачек из этих отраслей.

Так что — ждем :)
нихрена себе задачки «для начинающих»((
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории