Category Archives: Мысли вслух
На днях вспомнил об одной задаче, которая мне попалась на работе года полтора назад.
В то время я еще не знал об sql-ex.ru и мои познания в SQL были достаточно слабыми, на уровне
простейших селектов с inner join’ами. И, как я помню тогда, я не смог решить эту задачу без
дополнительного подзапроса. Сейчас, после нескольких десятков решенных задач на sql-ex.ru я
без проблем с ней справился, что навело меня на мысль о том, что это – неплохой тест на знание
азов SQL. В отличие от более сложных задач, эта задачка не требует большого количества времени, но
покрывает почти всё, что требуется для среднего программера в вопросе знания SQL, особенно если решать её в уме. Сразу отпадают вопросы наподобие “что такое JOIN, чем LEFT JOIN отличается от INNER JOIN, как работает группировка” итд.
Итак, формулировка такова. Есть 2 таблицы – Collection и Item.
Необходимо сделать выборку
Collection.ID Collection.Name Collection.Count
тех коллекций, которые содержат меньше 5 элементов.
Вот и всё.
ДАЛЬШЕ СПОЙЛЕР, НЕ ЧИТАТЬ !!!111 (Я не научился пока скрывать в вордпрессе куски постов, но как только научусь – оформлю соответствующе).
Алгоритм решения задачи.
Ну ясно же – надо сделать JOIN, делаем JOIN, группируем по Collection.ID, выводим ID, Name, Count(*).
Черт. При группировке по ID нельзя вывести Name. Значит, надо либо завернуть полученную выборку в еще 1 запрос, либо дописать в группировку этот Name. Ок, работает. Только пустые коллекции не выводятся. Почему ? Ну ясно же – они не попадают в результат INNER JOIN’a, надо использовать LEFT JOIN. О, теперь получилось. Только коллекции-то пустые, а count(*) выводит единицу вместо нуля. Ах да, это же LEFT JOIN, он джойнит Collection.ID Collection.Name NULL NULL и count(*) дает единицу. Как поправить-то. Вычесть 1 нельзя, поскольку так можно запороть непустые коллекции. Надо как-то проверить, является ли коллекция пустой, и для нее вывести 0, а для остальных – count(*). Да у нас же справа NULL, можно их в какую-нибудь агрегатную функцию запихнуть, и сравнить с NULL’ом. Если NULL, значит, коллекция пустая, и для нее выводим 0, иначе – count(*). Эврика! Ну и добавляем HAVING. Пишем запрос:
SELECT c.ID, c.Name, CASE WHEN COUNT(*) = 1 AND MAX(i.CollectionID) IS NULL THEN 0 ELSE COUNT(*) END FROM Collection c LEFT JOIN Item i ON c.ID = i.CollectionID GROUP BY c.ID, c.Name HAVING COUNT(*) < 5 |
Обычно считается, что фреймворки для разработки полезны тем, что предоставляют возможность программисту пользоваться некой готовой инфраструктурой. То есть основной плюс – в том, что ДОБАВЛЯЮТСЯ ВОЗМОЖНОСТИ использовать готовое. Но мне в последнее время кажется, что главное преимущество даже не в этом, а в том, что фреймворки, как правило, помимо дополнительных возможностей также накладывают существенные ограничения на код, который будет в рамках него работать.
Пример – Spring MVC предлагает только несколько стандартных способов написать обработчик запроса. Хочешь обработать запрос – пропиши маппинг и добавь метод в контроллер. Хочешь датабиндинг – используй @ModelAttribute. Почему это хорошо ? Потому что разработчику нужно меньше шевелить мозгами, раздумывая над тем, как бы лучше запрограммировать этот кусочек. Больше времени останется на продумывание более важных вещей. Плюс к этому, все, кто знакомы со Spring MVC, будут с первого взгляда понимать то, что хотел сказать программист Вася, написавший этот код года два назад. Значит, добавление ограничений положительно влияет на процесс разработки ? Получается, так.
Действительно, имея широкий набор возможностей, тяжело научиться их правильно использовать. Причем, как правило, сначала учишься использовать правильно, набивая шишки, и попутно придумываешь правила сам. Некий кодстайл, паттерны для того, чтобы писать корректный код, не думая о деталях. Так я учился в своё время языку С++. Читая описание того, что такое header-файл, я нигде не мог найти аргументированных правил по его использованию. Сейчас такая литература появилась в изобилии, но в то время у меня еще не было интернета. И я долгое время не знал, как оформлять h-файлы и как их инклудить в cpp – что именно должно быть в h-файле, а что – в cpp, можно ли инклудить h-файл в другой h-файл; если cpp-файл использует h-файл, зависящий от другого, то нужно ли в cpp-файл включать эту зависимость итд. Поэтому сидел и морщил ум на тему, как же сделать правильно. А всё потому, что С++ предоставляет множество способов сделать это НЕправильно, а очевидности, очевидные для опытных программистов, далеко не так очевидны для новичков. Аналогичные шишки приходилось набивать и на других платформах. C#, к примеру, заставил меня призадуматься о стратегии обработки исключений и особенно о корректной реализации IDisposable в иерархии классов.
Поэтому хороший фреймворк должен не только предоставлять пачку возможностей, но и набор несложных правил о том, как, собственно, писать код. Чтобы лезть в декомпилятор/исходники/дебагер приходилось как можно реже. Codestyle & FAQ – идеальные форматы для такой информации.
Как известно, за последние несколько лет в интернетах появилось и разрослось движение Интернет бомжей. Основная идея сферического бомжа в вакууме заключается в том, чтобы заработать побольше денег “в интернете”, не работая “на дядю” в реале. Заработок, к которому стремится среднестатистический бомж – так называемый “пассивный”, т.е. один раз сделал какую-то сеть сайтов, продал ссылки, разместил рекламку – и сиди, кури сигару, в раздумьях, как бы еще срубить бабла, ну или делай следующую партию сайтов в то время как денежки капают. У каждого не обремененного огромными доходами человека, который заходит почитать бомжеблоги успешных бомжей, возникает естественная мысль – почему бы тоже не попробовать ?
У меня двойственное отношение к этим бомжам. С одной стороны, это конечно круто – иметь собственный доход, не зависеть от начальства в реале, не платить налоги, постоянно развиваться итд итп. Но с другой стороны – какова цель всего этого ? Деньги. И люди тратят годы на то, чтобы сделать (уточню – не заработать, а сделать) деньги с помощью сомнительных средств (как то – наебалово доверчивых пользователей (к примеру, через смс), наебалово поисковых машин). Ну добыл денег – что дальше ? Прожигать жизнь или детям рассказывать, как юзеров-лохов на смсках разводил ? Ладно, опустим моральный аспект. Допустим, бомж работал несколько лет таким способом, и опыт у него – исключительно в поднятии денежных средств. А если этим заниматься не интересно ? Ну вот нравится если рыбу ловить – что, всю жизнь тратить на SEO ? Или мне, например, нравится программирование, музыка, и все, что с этим связано – мне совершенно неинтересно клепать сайты и искать способы подороже их втулить. Вопрос – как найти интересующую область деятельности, не “работая на дядю” и с приличным доходом ? Недавно видел на хабре пару постов от так называемых независимых разработчиков. Но – так ли они независимы на самом деле ? У обоих весь доход – от флеш игрушек. Интересно, им не надоело еще эти игрушки клепать ?
То же самое относится и к фрилансу – фрилансер волен лишь выбирать заказчика, но продукт и то, каким он будет – не в его власти.
В общем, крутость бомжевания, фрилансирования и независиморазрабатывания лишь поверхностна. А то, кем быть и как трудиться – дело выбора каждого, в зависимости от личных предпочтений и поставленных целей. И вопрос – как заработать приличные деньги, приобрести ценный опыт и пассивный доход, работая в интересующей области – по-прежнему остается открытым.
5