• Хорошая ли практика создавать свои классы Exception для отлавливания разных ошибок?

    @WhoMe
    UPD:
    > Это нормально что в контроллере столько много catch'eй?
    Не то чтобы нет, но "попахивает".
    > как быть, если у меня возникает несколько исключений, и я хочу выдать пользователю информацию о всех возникших сразу

    У вас смешана валидация входных параметров с возникновением нештатных ситуаций.
    Exception стоит кидать если метод не может вернуть осмысленный результат.
    Ошибки валидации ("сообщение слишком длинное", "файл не того расширения") можно собирать, к примеру, в массив. Как валидировать входные данные выходит за рамки этого вопроса.
    ------
    > Можно ли так делать?
    Попробуйте использовать правило 5 почему (ну или "зачем") чтобы попытаться добраться до сути.

    - Я даю отдельные имена исключениям.
    - Зачем?
    - Для того что бы отловить различные ошибки.
    - Зачем отлавливать различные типы ошибок?
    - Чтобы показывать разные сообщения.
    - Зачем показывать разные сообщения?
    - Чтобы пользователь мог отреагировать определенным образом на конкретный тип ошибки
    (решить что ему делать в случае конкретного исключения).

    Давайте посмотрим что человек (пользователь) на вашем сайте (системе) может сделать в случае ошибки:
    1. Не корректное сообщение.
    Привести его к корректному (сделать его короче, как-то отформатировать и т.п.)

    2. Не удалось загрузить файл.
    Если файл слишком большой - можно попробовать загрузить файл поменьше.
    Если это внутренняя ошибка (например: закончилось место на диске на сервере, нет прав на запись и т.п) - то ничего, здесь уже требуется вмешательство тех кто обслуживает систему.

    3. Ошибка PDO.
    Ничего, это внутренняя ошибка.

    Т.е. есть смысл создавать новый тип исключения, если пользователь системы может иначе отреагировать на этот тип.

    Я использую 2 типа исключений на уровне web-слоя: внешние и внутренние.
    Внешние - если пользователь может повлиять на них (страница не найдена, файл слишком большой, нет доступа и т.п.).
    В них сообщение показывается пользователю как есть. Подноготная (пути к файлам, пароли, названия БД и т.п) в такие ошибки не вкладывается.

    Внутренние - пользователь не может влиять (ошибка подключения к БД, SQL syntax error и т.п).
    Пользователю показывается только код ошибки. В такие ошибки также вкладываю техническую информацию.

    Ты (как программист) также можешь быть пользователем какой-то системы (к примеру, библиотеки).
    Например, библиотеки для работы с БД.
    Предположим ты импортируешь csv-файл в базу, заполняешь числовую колонку и вместо числа у тебя попадается текст.
    Запрос падает с ошибкой и тебе не плохо бы отличать её от ошибки синтаксиса.
    Если попался текст вместо числа - то можно просто пропустить строку.
    Если ошибка синтаксиса - то у ошибка в коде и продолжать импорт нет смысла.

    Подытожу:

    > Можно ли создавать свои пустые классы Exception'ов наследуемые от класса Exception только лишь для того что бы было отдельное имя исключения?

    Можно.

    Сколько делать отдельных исключений?
    Зависит от того как их будет обрабатывать пользователь.
    Если твой контроллер(модель, подсистема) кидает множество разных ошибок и все они обрабатываются одинаково - то стоит призадуматься.
    Ответ написан
    3 комментария
  • Возьмут ли на стажировку в Москве, если диплом не по специальности связанной с IT?

    @WhoMe
    На дипломы жуниоров обычно всем класть. Бесплатную не надо, да и вряд ли найдете, идите на оплачиваемую.
    Про "заслуги" на собеседовании узнаете.
    Ответ написан
    1 комментарий
  • Почему sphinx не ищет кириллицу?

    @WhoMe
    Пальцем в небо
    sql_query_pre = SET NAMES utf8
    Ответ написан
    1 комментарий
  • Как понять момент в замыкании(JS)?

    @WhoMe
    Уже разобрались?
    Всё работает.
    Вызов makeCounter() каждый раз создает новую currentCount и возвращает новую функцию.
    console.log( makeCounter() () );
    console.log( makeCounter() () );

    Будет примерно эквивалентно
    var counter1 = makeCounter();
    var counter2 = makeCounter();
    console.log(  counter1() );
    console.log( counter2() );
    Ответ написан
    1 комментарий
  • Программист в Японии?

    @WhoMe
    Вот на этом видео чувак (появлется на 1 мин) частично отвечает на Ваш вопрос.
    www.youtube.com/watch?v=cUY3YFQsYMg

    Вижу, что Вы еще не особо представляете на что подписываетесь, хотя возможно и сами не осознаете.
    Чтобы "посетить" страну, не обязательно там оставаться. Съездите в яз. школу на 1-3 месяца (возможно, с продлением до года, школы довольно гибки как по срокам, так и по оплате, узнавайте).
    В школах процентов 80 ищут пути остаться, походите по школам, поопрашиваете самих студентов и их знакомых/друзей кому "удалось".
    Заодно проверите свои намерения, вернетесь либо воодушевленным, либо удовлетворенным. 3 месяца хватит за глаза.
    Я Вас не отговариваю, просто предостерегаю, что ваше текущее представление о Японии соответствует действительности процентов на 10.
    У новоприбывших из-за этого стрессовое состояние в первые дни адаптации.
    Ответ написан
    2 комментария
  • Можно ли избежать принудительного возврата false в C#?

    @WhoMe
    Вы что-то путаете, наверное имеется ввиду не if, а само ветвление.
    Если у метода определено возвращаемое значение - в данном случае bool - то оно должно быть возвращено(либо брошено исключение).
    Каждый участок в коде на котором завершеается выполнение метода (терминальная ветвь) должен возвращать значение (за исключением случая, когда возвращаемое значение отсутствует, т.е void), либо кидать Exception.

    Рассмотрим код:
    public bool Func(int k)
            {
                if (keyboard.ContainsKey(k))
                {
                    return keyboard[k];
                }
    
               // убираем return false;
            }
    
    // ... и где-нибудь вызываем
    bool val = obj.Func(1);


    Допустим ключа 1 не нашлось в keyboard, что в таком случае по вашему должно оказаться в val?
    Возникает неопределенность. Поведение программы становиться непредсказуемым. Одна из целей ЯП выского уровня как раз в предотвращении таких ситуаций.
    Т.е перехитрить C# нельзя. По крайней мере не в исходном коде.

    Принудительный возврат сделан специально, чтобы снизить вероятность ошибки. Терминальную ветвь не всегда легко увидеть на глаз. А еще устраняет неопределенность: то ли ты забыл поставить возврат (ошибся), то ли так и задумывалось.
    Ответ написан
    Комментировать
  • Как выбрать данные за каждый час из базы SQL?

    @WhoMe
    Как-то так
    ...
    WHERE 
     DATE(date) = CURDATE()
    GROUP BY
      EXTRACT(HOUR FROM date)
    ORDER BY
     EXTRACT(HOUR FROM date)

    Но 24 записи будут не ранее 12 часа ночи.
    Нужно уточнить. Что значить "выбрать temp, hum и date"? Их сумму, максимальное/минимально или что? В часе их около 12 штук, а записей всего предполагается ведь не более 24.
    Ответ написан
    3 комментария
  • В чем разница между \A и \Z, и ^ и $ (регулярные выражения) ?

    @WhoMe
    Сначала определимся с терминологией:
    string, строка - просто набор символов, который может включать в себя символ переноса строки.
    line, линия (хотя по русски мы говорим тоже строка [текста]) - набор символов без переноса строки.

    ^ и $ соответвсвуют началу и концу строки( string), но модификатор "m" может поменять это поведение и они будут означать начало и конец линии (line) соответсвено.
    \A и \z всегда соответвсвуют началу и концу строки, модификатор "m" не оказывает на них влияния. (\Z захватывает еще и перенос строки в конце)
    \A
    start of subject (independent of multiline mode)
    \Z
    end of subject or newline at end (independent of multiline mode)
    \z
    end of subject (independent of multiline mode)

    Видимо автор ответа предлагает дополнительно перестраховаться, если кто-то поставит модификатор m то регулярка /^\d{4}-\d{2}-\d{2}$/m будет так же пропускать ("матчить") строки вида "xss\n2014-08-31\nxss"
    $str = "<some>xss</some>\n2014-08-31\n<some>xss</some>";
    $r = "/^\d{4}-\d{2}-\d{2}$/m";
    var_dump($r, preg_match($r, $str, $m), $m);
    /*
    string(22) "/^\d{4}-\d{2}-\d{2}$/m"
    int(1)
    array(1) {
      [0]=>
      string(10) "2014-08-31"
    }
    */
    Ответ написан
    3 комментария
  • Имеет ли важность для Java EE работодателя опыт работы Android разработчиком?

    @WhoMe
    Я полтора года назад устраивался на должность Junior Java EE разработчиком в Москве.
    У меня не то что опыта Java EE разработки не было, у меня не было даже трудовой книжки.
    В резюме так и написал: мол опыта Java EE нет, но про Java слышал, про спринги всякие читал,
    ну и приложил ссылочку на свой репозиторий на гитхабе с опенсорс-библиотечкой на Java (ничего особенного, простая обертка над API сайта, день-два работы).

    По моим ощущениям, если у тебя нет опыта в Java EE, то у тебя нет опыта в Java EE и им пофиг че ты делал до этого.
    У меня на собеседовании даже не спрашивали что я писал (кроме вышеуказанной библиотеки), какие проекты делал (до этого я немного фрилансил на php)
    и с чего я решил что знаю Java. Дали бумажный тест по Java и SQL. Потом побеседовали по основам java: коллекции, потоки, синхронизация и т.д.
    по базам: типы связей (один-к-одному/один-ко-многим/многие-ко-многим), транзакции, ACID и в таком духе, ну и в общем плане: процессы, потоки, http-протокол.
    Видимо я не слишком сильно плавал в вопросах, а может их просто устроили мои скромные запросы по ЗП (скромничать, кстати, не советую, выйдет боком, но это уже другая история).
    Меня взяли.

    Вместо постскриптума.
    За неделю работы там я узнал больше чем за пару месяцев самостоятельного изучения спринга и Java EE в целом.
    Java EE на самом деле очень обширная область, а Java SE это так, верхушка айсберга.
    Мозги реально кипели от объема поступаемых новых данных, попутно приходилось дома читать книжки и добирать основы где не хватало.
    Еще смешное, в Java EE на 5 строк java кода приходилось строк 20 xml конфигурации :D Видимо поэтому не особо гоняют по самой Java. Больше времени тратишь на настройку и свзку всяких фреймворков и серверов.

    В общем, налегайте на основы, читайте и самое главное пишите.
    Когда начинаешь писать сразу всплывает куча нюансов и непонятных java экспешенов (куда же без них).
    И еще, если с английским проблемы, налегайте на английский. Вся документация на английском.
    На русском либо её нет вообще, либо её крайне мало, либо она уже устарела.

    Отвечая на Ваш вопрос(имхо, по моим ощущения и по опыту чтения форумов): опыт Android-разработчика _преимуществ перед_ Java EE-работодателем вам особых не даст.
    Android платформа с Java EE имеет мало общего, но хуже от него само собой не будет.

    Извините за многобукаф, Остапа понесло.
    Ответ написан
    Комментировать
  • Как программировать игры?

    @WhoMe
    Еще книженция. Сам не читал, но выглядит интересно, вроде по делу все
    gameprogrammingpatterns.com
    Ответ написан
    Комментировать
  • Отправка данных с сервера к клиенту по 1 сокету.C++

    @WhoMe
    Не гуру, но вставлю свои 5 копеек.

    Общий принцип работы (для блокирующихся сокетов)
    Клиент (тут все просто):
    - Создаем сокет (ClientSocket)
    - Конектимся к серверу
    - Пишем/читаем в/из ClientSocket

    Сервер:
    - Создаем сокет (ListenSocket)
    - Вызываем accept (поток блокируется пока не подключится клиент или не произойдет ошибка)
    - Accept возвращает сокет (ClientSocket), он ассоциириован с нашим подключившимся клиентом.
    Если мы хотим отправить/прочитать данные в/из этому клиенту, то читаем/пишем из/в ClientSocket.
    - Если мы хотим "принять" еще одного клиента, то снова вызыаем Accept

    Еще раз. Если у нас к серверу подключены, скажем, 5 клиентов. То у нас получается 6 сокетов: 1 слушающий + 5 клиентов.

    Будет не лишним отметить некоторые особенности при работе с блокирующимися сокетами.

    Возьмем к примеру клиентскую часть.
    Вы нажимаете кнопку в интерфейсе, вызывается функция, например button1_Click.
    Создается socket и вызывается функция connect. В этом месте поток блокируется пока сокет не соединится или не произойдет ошибка.
    (Аналогично с accept в серверной части) Т.е Ваша программа визуально "подвиснет". Интерфейс перестанет реагировать. То же касается чтения и записи.
    Решением может быть создание отдельных потоков для работы с сокетами, либо использование мультиплексированного ввода/вывода.

    По вашему коду:
    1.
    send(s, buf, 50, 0);
    Отправляете данные не в тот сокет. Надо в sa. (См. sa = accept(s, 0, 0); // block for connection request)

    2.
    ioctlsocket(sa, FIONBIO, &mode);
    bytesRecv = recv(sa, recvbuf, 50, 0);
    err = WSAGetLastError();// 10057 = A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) 
    if (bytesRecv == 0 || bytesRecv == WSAECONNRESET) {

    Т.к вы переключили сокет в неблокируйщися режим возвращение нуля тут штатная ситуация. Также обратите внимание на bytesRecv == WSAECONNRESET, сравнение явно не с той переменной.

    См. также
    habrahabr.ru/post/111357
    Ответ написан
    1 комментарий
  • Кол-во запросов к MySQL

    @WhoMe
    Как-то давно тоже задавался таким же вопросом, и получил такой же ответ "Похер. Главное чтоб не тормазило".
    Понятия не имею сколько у меня запросов к базе на проектах. Хорошим тоном является отсутствие бесполезных/нерациональны запросов,
    или там запросы в цикле (Хотя могу поспорить, что в каком-нибудь отдельном случае, теоретически, это может быть рационально и тогда это не будет плохим тоном).
    Это чисто психологическое. Если хотите цифру, давайте назову, скажем не более 15.
    Ответ написан
    Комментировать
  • Чем отличается "alter ... modify" от "alter ... change"?

    @WhoMe
    dev.mysql.com/doc/refman/5.1/en/alter-table.html
    Если посмотреть документацию то можно заметить, что для CHANGE также указывается новое имя колонки, в то время как в MODIFY меняется только ее описание.
    | CHANGE [COLUMN] old_col_name new_col_name column_definition
    [FIRST|AFTER col_name]
    | MODIFY [COLUMN] col_name column_definition
    [FIRST | AFTER col_name]
    Ответ написан
    Комментировать
  • Как реализовано?

    @WhoMe
    Дело в том, что URI не обязан проецироваться на файловую систему, т.е на www.website.net не обязательно должна быть директория PAGE, просто такое поведение установлено по умолчанию. Погуглите по слову mod_rewrite
    Ответ написан
    2 комментария
  • Как работает Libevent?

    @WhoMe
    Висит. Libevent не добвляет никакой магии и предполагает работу с неблокирующими вызовами. У Вас таких нет.
    Ответ написан
    Комментировать