[Из песочницы] История одного программиста
Кажется, что еще совсем недавно мне было 20 лет, я сидел в кофейке с друзьями и бросался словами на ветер о том, что застрелюсь к 25 годам, если не стану долларовым миллионером. Сейчас мне 28, и если бы мне пришлось услышать подобное, я бы посочувствовал наивности этого человека.
Как все началось. Учеба.
Моя история знакомства с Интернетом началась еще в старших классах, мой одноклассник набросал простенький сайт для друга своего отца, а тот ему за это заплатил. Меня это сильно впечатлило, в результате чего появилось еще два клона этого HTML сайта с разницей лишь в цвете, которые я успешно кому-то продал. Я еще долго продавал этот шаблон, пока совсем его не заездил. В те годы конкуренция еще не была такой жестокой, достаточно было дать объявление о создании сайтов, и на следующий день у тебя, школьника 9-го класса, за деньги готовы были заказывать сайты взрослые люди.
После окончания школы все решилось само собой, с мат. класса на мат. фак. (программирование). Забавно сейчас вспоминать, как мне в начальных классах говорили: «Куда тебе в математическую школу, ты даже 80 слов в минуту не читаешь». Затем в старших классах при разделении на обычный и математический класс учительница по математике сильно удивилась, что я иду в мат. класс, хотя сама она его не вела. Хорошо, что дальше уже были адекватные учителя.
При поступлении в универ никто ничему не удивлялся, все суетились, сдавая тесты. Я как вчера помню день вступительных тестов, сразу стало понятно, что решать задачи в реальном времени не получится, они сильно отличались от тех, на которых мы тренировались. Да и вообще быстро думать, тем более в стрессовой ситуации, явно не мой конек. Я переписал все тесты, кстати, я был не один такой умный, все наши 5 человек (мои одноклассники) сделали то же самое. Далее был перерыв на 3 часа, на котором мы с одноклассником разбирали тесты, затем — очередная сдача. Потом мы еще все лето разбирали с репетиторами списанные задачи, и в конце лета было еще одно тестирование. Всего было 3 тестирования, но в итоге оказалось, что самое первое тестирование все остальные прошли настолько плохо, что у нас были самые высокие балы. Недолго думая, я и четверо моих одноклассников пошли на специальность с самым высоким проходным балом. Пошли все, а из 30 поступивших вовремя закончило 3-ое, на следующий год еще несколько человек доучилось. Провальным был именно наш год, курсы до и после нашего были вполне успешными. Я тоже успел повисеть в списках на отчисление, причиной была музыка, я так сильно ей тогда увлекался, что на учебу не хватало времени. Забавно до сих пор видеть страницу на Promodj со своими треками.
На третьем курсе мне пришлось сделать первый трудный для меня выбор в моей жизни: или музыка, или учеба. Я прикинул, что дала мне музыка, и что дало мне программирование. Музыка в результате больших трудозатрат дала мне несколько отзывов из серии «ну да, неплохо», программирование дало мне все остальное — деньги на все музыкальное оборудование. Выбор был сделан, на следующий день все диски, которые не имели ценности, были выброшены, а музыкальное оборудование ушло с молотка.
Потребность в креативе нашла свой выход в программировании. В тот год один из предметов у нас вел легендарный преподаватель старой закалки Гаврилова Татьяна Леонидовна, именно у неё я научился видеть программы, как механизм, состоящий из других механизмов, которые состоят из деталей. Не зря программы иногда называют движками. Начав программировать над ее задачами, я, наконец, понял смысл уравнений математики для описания реального мира, но меня по-прежнему привлекал интернет.
Как мы делали веб-студию. Первые шишки.
К концу третьего курса учебы в университете я решил устроиться на работу связанную с программированием и Интернетом. К тому моменту я немного знал PHP, выучив его основы, делая заказные сайты. Если учесть, что университетским стандартом был старый добрый C++, то проблем не было, не хватало опыта. Я открыл доску объявлений и выбрал первое более-менее подходящее объявление. Небольшая ЗП, знание PHP, основы английского, работа была связана с сайтом знакомств. Здорово — подумал я, сходил на собеседование и… обломался. За мизерную ЗП уровень английского и прочие требования были весьма значительными. Это был мой первый урок, очень часто работодатели имеют ограниченный бюджет, в результате чего появляются вакансии с диссонансом уровней ЗП и требований. Тот, кто обладает требуемым набором навыков, не станет работать за такую ЗП, а те, кто не дотягивает, получают удар по самооценке. В некоторых случаях самооценку занижают намеренно, чтобы сбить цену. Следующая вакансия была более удачной, правда ждать пришлось несколько месяцев, мне пообещали собеседование, и пропали, пришлось самому о себе напомнить, позвонив еще раз. Никто не задавал мне бесполезные задачки, а было интересное тестовое задание: есть японский интернет-аукцион автомобилей, нужно вывести его у себя на сайте (сделать зеркало). Так все и закрутилось: сокеты, генерация запросов, парсинг ответов сервера аукционов, перевод через online-переводчики.
За год я полностью переписал весь сайт компании, попросил поднять ЗП, а потом снизить ЗП и нанять в помощники моего одногруппника, опыт совместной работы лучше сиюминутной выгоды. К тому моменту он своей дорогой также пришел к PHP. Вместе мы вышли на новый уровень сложности, стали пилить большие задачи пополам, контроль версий был просто открытием. В некоторых задачах требовались десктоповые приложения, я писал их на Java, а бекенд на PHP писал мой друг.
В какой-то момент я предложил своему работодателю открыть подразделение для создания сайтов. Компания имела много партнеров, и периодически той или иной дружественной компании требовался сайт, а мы оказывали только консультации. Сначала мне отказали, а когда наступил кризис, нам сначала срезали ЗП, а затем решили вернуться к вопросу веб-студии, но было уже поздно. К тому моменту мы с товарищем написали свою CMS, сделали на ней пару сайтов и были в стадии покупки ООО для открытия веб-студии. Мы считали, что если все сделать как надо, то клиентов у нас будет больше. По нашей логике их должно было привлечь заключение официального договора, оплата по безналичному расчету и т.д. Через пару недель мы объявили об уходе из компании, я стал гордо именоваться директором, и мы были учредителями собственной фирмы с долями по 50%. Желание открыть ООО — это самое большое заблуждение начинающих предпринимателей. ООО для маленькой компании ничего не приносит кроме проблем: 10000р. стоили услуги юристов по открытию ООО, около 3000р. открытие счетов в банке, еще сколько-то в месяц за ведение счетов, около 1000р. за предоставление юр. адреса (своего у нас не было), 5000р. в месяц бухгалтеру и еще огромная куча времени, потраченная на хождение по различным инстанциям. Возможно сейчас ситуация как-то изменилась с появлением сервисов вроде «МоеДело» и электронной отчетности, но в случае электронной отчетности появилось куча фирм посредников, роль которых давать фирмам доступ к серверам гос. структур за деньги. Ко всему прочему добавлялись налоги, просто так деньги вывести со счета нельзя, либо трудоустраивайся, либо выводи как дивиденды учредителям с немалыми процентами. С учетом всех расходов выходило, что мы тратили 30% своей прибыли на содержание этого карманного монстра. К тому же кризис (тот самый первый кризис в 2009) давал о себе знать, сайты заказывали уже не так охотно. Все закончилось тем, что через 5 месяцев наши расходы превышали доходы. Денег, которые мы зарабатывали, хватало на одного, но не на двоих. В итоге наш последний заказчик предложил мне работу в качестве управляющего интернет-магазином, который мы ему сделали. Моему напарнику достались все наши текущие клиенты (которые платили помесячно), что по прибыли как раз составляло мою новую ЗП.
Первый вывод, который можно сделать из всего этого — не теряйте свой основной источник доходов, работайте на вашей основной работе, пока не убедитесь в стабильности и надежности прибыли, которую приносит вам ваше дело. Потеря основного источника дохода какое-то время будет вас стимулировать, но не все в этой жизни зависит от вас, темп роста может оказаться совсем не тем, который вы ожидаете, в итоге вам необходимо будет на что-то жить. Что касается юридического оформления компании, оно должно быть следствием появившегося бизнеса: сначала бизнес, потом прибыль, потом ООО. Налоговой нет до вас дела, если у вас не хватает денег даже на содержание ООО.
Как мы делали интернет-магазины в аренду
Идея собственного сервиса всегда меня привлекала. По моему личному мнению программисту выгоднее продавать готовый результат своей работы, чем свои услуги. Продавать свой готовый продукт гораздо сложнее, но этот процесс легче формализовать, а, следовательно, он лучше масштабируется, что говорит о перспективе дохода превышающего среднестатистическую зарплату.
Продавая услуги, я ни разу не встретил два одинаковых проекта, каждый проект всегда уникален, уникальные задачи, уникальные проблемы. Крайне редко удается предсказать реальные сроки разработки. Завысил стоимость, чтобы покрыть риски, получил неконкурентный ценник и потерял клиента. Занизил стоимость и не угадал срок, работаешь себе в убыток, есть вариант бросить клиента, но я так ни разу не делал.
История аренды интернет-магазинов началась в 2008, появилась идея интернет-витрины для компаний — компании не создают себе интернет-магазины, а пользуются готовым сайтом для размещения своих товаров. Товары одной компании выводятся как в отдельном разделе, так и в общем каталоге. Мы с моим напарником написали зачатки функционала, третий участник нашей команды должен был организовать нам лояльных первых клиентов. По своей наивности мы предполагали, что информацию о товарах будут заносить сотрудники этих самых первых компаний-клиентов, но, как выяснилось, не у всех вообще были компьютеры или доступ в интернет, не говоря уже о навыках работы на компьютере и каком бы то ни было желании заниматься этим. Если нежелание еще можно было компенсировать приказом начальства, то остальное было серьезной проблемой в нашей схеме. К тому же идея была слишком общей, все для всех. Один из моих знакомых посоветовал мне уточнить идею, сделать её более понятной, так мы переключились на автоматизированную аренду интернет-магазинов.
На тот момент я и мой напарник уже работали каждый на своей работе, потерпев неудачу с открытием веб-студии. Мы никуда не спешили и хотели сделать отличный проект. Рассчитав ожидаемую сверхвысокую посещаемость и нагрузку, решено было сделать распределенную архитектуру — выделить связанный функционал в отдельные сервисы и разнести их по разным серверам. Со временем планировалось добавлять новые сервисы. Изначально был определен следующий список сервисов: авторизация, финансы, аренда-магазинов, технический сервис. Между собой сервисы переговаривались в JSON формате. Средой разработки стал Grails.
Сейчас это выглядит как неудачный план по захвату Мира, но на тот момент все казалось вполне логичным. Возможно, система и выдержала бы ту абстрактную высокую нагрузку, но никакой нагрузки не было. Сложность проекта привела к сложности реализации, все силы ушли на программирование основы. Когда мы дошли до реализации самого сервиса аренды магазинов, моральные силы были практически на исходе. Согласно первоначальному проекту магазины должны были включать в себя широкий набор инструментов визуального редактирования, всевозможные виджеты и т.д. Но оценив выполненный список работ и объем потраченного времени, мы не хотели ждать еще полтора года.
Решением стал автоматический запуск отдельных сайтов на базе Booot CMS. На наш взгляд это было самое простое решение, которым смог бы управлять не профессионал. В пару кликов на сервере создавался новый сайт, в корень которого извлекался скрипт Booot CMS, после чего в конфиги прописывались доступы к базе. Через нашу панель управления можно было установить пароль на новый магазин и перейти в панель управления магазином Booot CMS.
Клиентам нравилось, что была возможность за дополнительную плату перенести магазин к себе на хостинг. Аренда магазина стоила 300р./мес., а выкуп 5000р. В сравнении с теми решениями, которые существуют сейчас, это детский лепет, но на тот момент после рекламы в 10000р. на Яндекс.Директ у нас даже появилось несколько активных клиентов, не говоря уже о зарегистрированных пользователях. Кстати Яндекс.Директ тогда обходился в два раза дешевле.
Пара клиентов и десяток регистраций были явно не тем результатом, который мы ожидали увидеть спустя два года работы в свое свободное время. Я планировал продолжить рекламу в следующем месяце, но мой партнер уже потерял всяческую веру в проект, у него был годовалый ребенок, и ему было не до того. Я и сам порядком подрастерял энтузиазм, несмотря на то, что все сервисы крутились на одной VPS, даже оплата сервера на следующий месяц была для меня большой проблемой при уровне моей новой ЗП, не говоря уже о рекламе. В итоге я перенес арендуемые магазины на Booot CMS на новый более дешевый сервер, на котором крутилось еще несколько других моих клиентов, которым я когда-то делал сайты.
Очевидно, что изначально выбранная сложная архитектура была неоправданна. Всегда хочется написать интересно, красиво, универсально и на века, но надо уметь себя контролировать. Нужно выбирать базовый действительно необходимый функционал, в расчете на то, что проект не пойдет. При создании нового проекта, лучше настраивать себя на то, что вы делаете первую тестовую версию проекта, нагрузка и прочие вещь вас совершенно не должны волновать в этот момент. Выживают лишь единицы из сделанных проектов, и если случится чудо и пойдет нагрузка, уж справиться с этим как-нибудь будет можно. В первую очередь можно повысить производительность VPS, а далее оптимизировать запросы, да даже переписать проект заново, вы будете знать для чего и что вы делаете.
Второй ошибкой было бросить проект без боя. Была проделана огромная работа, и получен инструмент, с помощью которого можно было хотя бы исследовать рынок, проверить эффективность тех или иных видов рекламы, оценить поведение и предпочтения пользователей. Должно было появиться заключение с большой долей вероятности указывающее, почему не пошел проект. Но я ничего этого не сделал. Возможно, здесь сыграли роль личные обстоятельства, я переусердствовал с бессонными ночами, подорвал иммунитет и сильно заболел гриппом, после чего еще несколько лет чувствовал сильную слабость — еще один урок, берегите себя, тише едешь — дальше будешь.
Эта мысль не давала мне покоя еще несколько лет, за это время я еще раз вернулся к попытке создания веб-студии (об этом ниже), после чего все же реинкарнировал магазины.
Восстановив магазины спустя несколько лет, я понял, что поезд ушел. Ценник на Яндекс.Директ стал дороже в два раза, бюджет был тот же, кликов в 2 или даже больше раз меньше, а регистраций 0. В итоге появилась вторая версия магазинов на Symfony2, которая ориентирована на начинающих пользователей, небольшие магазины с базовым набором необходимых функций, по ней выводов пока не очень много, воспринимается она лучше.
2-я попытка запуска веб-студии. Кто ждет — тот…
Спустя год управления интернет-магазинов в качестве директора, я решил вернуться к идее создания веб-студии. Видимо не сиделось мне без подработки. Основываясь на первом опыте, я решил делать все постепенно, никаких увольнений с текущего места работы, никаких ООО, только наработка клиентов, оценка ошибок и их исправление. По поводу прибыли я тоже решил не волноваться. Настроив себя на долгосрочные перспективы, я установил средний ценник на свои услуги. Первым делом мне нужен был сайт моей студии, я взял яркий готовый шаблон и подправил тексты в его оформлении. В качестве названия решил взять что-то простое и русское, получилось «ЧерезВеб». Следом дал рекламу на местной доске объявлений. Конкуренция заметно выросла за прошедший период, звонков не было. Я откопал все свои прошлые работы, сделал скриншоты для портфолио — звонков не было. Тогда я добавил массу всяческих полезных для заказчиков текстов на сайт, которые сам написал — звонки пошли.
Понемногу у меня стали появляться клиенты, но типовые сайты никому не были нужны. Всем нужны были уникальные проекты: уникальный функционал, уникальный дизайн. Так как разработку я вел на CMS Joomla, то проблему с дизайном в большинстве случаев мне удавалось решить за счет http://templatemonster.com/. С функционалом было сложнее, если и удавалось найти готовый модуль, он работал не так, не так выглядел, в итоге приходилось писать свое решение или сильно изменять готовое.
Ко мне обращалось много людей, которых кинул предыдущий исполнитель, после начала работы с ними я понимал, почему он так поступил. Чтобы сохранить свои нервы, я все старался делать через технические задания. В MS Word описывался список страниц сайта, вставлялись их схемы (помогала программа https://balsamiq.com/products/mockups/ или http://dia-installer.de/), описывалось содержание страниц сайта, тексты, изображения, функции, кнопки, поля. Заказчики выдвигали множество противоречащих требований, которые, по их мнению, было легко реализовать, но когда дело доходило до формализации в виде технического задания, возникало множество вопросов. Не было текстов, не было изображений, выяснялось, что нужен еще какой-то функционал, о котором забыли упомянуть. Некоторые сразу заявляли, что так работать не могут, им надо увидеть и выбрать, я естественно отказывался от такой схемы, для меня это означало выполнить работы в несколько раз больше, но за те же деньги.
Спустя какое-то время я стал пытаться нанимать фрилансеров, чтобы перезаказывать программирование и дизайн, оставив за собой только обязанность менеджера проектов. Дизайн еще более мене поддавался делегированию, иногда дизайнер выдавала хороший результат, иногда какую-то хрень. Хрень получалась тогда, когда заказчик пытался в деталях объяснить, что именно он хочет видеть, а дизайнер привыкла рисовать типовые дизайны, а не что-то с нотками триптиха Густава Климта.
С программированием все было гораздо хуже. Если раньше мне не нравилось, как программирует мой одногруппник, с которым мы писали совместные проекты, то после того, что я увидел, я стал ценить его еще больше. Багов было так много, что мне приходилось вновь и вновь возвращаться к программированию, чтобы не затягивать проект еще на несколько недель. По сути ситуация была такой, что если бы я выставлял всем своим заказчикам реальные ценники, то ни один из них не заказал бы у меня сайт, но так как это была для меня подработка, я довольствовался тем что имел. В общей сложности, если поделить годовой доход, в месяц выходило около 15000р. — как раз моя первая зарплата в начале карьеры, но это был не тот доход, на который можно было уйти с моей основной работы.
Получалось, что всевозможных телодвижений было много, а дохода не было. Мне хотелось более сложных проектов, а заказчикам хотелось того же, но по цене визиток. В итоге я постепенно стал закручивать гайки. Сделал платным выезд и в почасовую оплату консультаций — это хорошая защита от клиентов, которые не ценят ваше время, ведь вы не обязаны всегда брать за это оплату, вы можете напоминать об этом клиенту, когда он чересчур назойлив. Забавно было наблюдать, как один из моих клиентов сначала в прежнем режиме стремился со мной встречаться, а потом заметно притих, после чего ему пришла в голову гениальная мысль узнавать все по телефону, причем в нерабочее время, так как днем он работал. Был случай, когда заказчица искренне не понимала, почему она должна переводить мне на карту 500р., и почему я не могу за ними приехать, а ехать надо было по пробкам через весь город, на бензин ушло бы 500р. плюс время. В какой-то момент мне стало казаться, что к разработчикам сайтов относятся как к студентам — бери, сколько дают, и радуйся. Кстати важно брать всегда предоплату, никогда ничего не делайте без предоплаты, были неприятные случаи, связанные с этим. Лучше не взять клиента, чем остаться в минусе.
Работа над заказными сайтами продолжалась пару лет, ничего не предвещало перемен. Как вдруг со мной списались двое предприимчивых парней моего возраста, которым требовалось разработать социальную сеть. Замах был серьезным, бюджет на разработку был адекватным. Я обрадовался удаче, подтянул своего напарника для совместной разработки, и мы с ним решили, что я делаю ТЗ, заказываю дизайн, а он в итоге все закодирует согласно ТЗ. Я спросил его, сколько ему потребуется времени на программирование, он назвал срок в 4 месяца, я добавил еще два и 3 на ТЗ и дизайн, итого проект должен был быть выполнен за 9 месяцев. Положиться на опыт своего товарища было самой большой моей ошибкой, опыт программирования у него был, а опыта оценки не было. Хотя я не исключаю, что я тоже бы не угадал со сроком. Когда пришло время сдавать проект, мой напарник находился еще где-то в начале пути, я понял, что он не успеет и начал ему помогать, так мы выучили Symfony2. Кодировали мы днями и ночами, в общей сумме на разработку ушло около 2 лет, естественно параллельно с работой. Заказчики были весьма терпеливы, возможно, причиной были промежуточные демонстрации написанного, но скорее всего то, что местный крупный разработчик оценил проект в 5 млн. рублей, что было на много дороже того, что запросили мы. Когда мой напарник доделывал проект, свою оставшуюся долю он уже и не надеялся от меня получить, но у меня почему-то и в мыслях не возникало её зажать. Надо отдать нам должное, проект мы довели до конца, до финиша дошли все, а с заказчиками я до сих пор в хороших отношениях. Долгострой назывался FlashBiz.
После крупного проекта на фреймверке Symfony2 я уже не хотел возвращаться к сайтам на заказ, я вспомнил, каково это — получать удовольствие от разработки. Далее на Symfony2 была написана вторая версия магазинов, о которых рассказывалось ранее.
Дата-центр на базе YOTA. Тернистый путь.
Когда мы писали FlashBiz, я понимал, что не вернусь к сайтам на заказ, я постепенно довел все свои заказы до логического конца, не принимая в разработку новые. Теперь о попытке создания веб-студии напоминали лишь несколько клиентов, размещающих свои сайты на моем сервере, это трудно было назвать хостингом, но что-то вроде того.
Когда FlashBiz проходил стадию тестирования перед сдачей я параллельно восстановил свои первые интернет-магазины в аренду для анализа причин неудачи проекта (то, о чем писалось выше).
Итого у меня был следующий зоопарк: сервер хостинга, сервер FlashBiz, сервер магазинов.
А еще в тот момент к нам в город пришла Yota, а IP был статический, а еще было несколько неиспользуемых компьютеров и лишние жесткие диски. Не знаю, навело ли вас это на какие-нибудь мысли о велосипеде, но меня навело. На компьютеры я установил Ubuntu Server и программный RAID 1. Весь свой зоопарк я разместил на виртуальных машинах VirtualBox и раскидал по компьютерам. Все компьютеры стояли на металлических стеллажах на складе.
Так как внешний статический IP был один, а внутренних серверов было много, то понадобился еще один виртуальный сервер, который я назвал балансировщиком. Балансировщик принимал внешние запросы и в зависимости от домена перенаправлял их на нужный сервер. Работал балансировщик на nginx, а механизм добавления и удаления доменов был на Grails. При привязке домена к сервису аренды магазина, домен через API автоматически добавлялся и на балансировщик, так была решена проблема динамического добавления новых доменов на сервис магазинов.
Самое интересное, что все работало. Работать с виртуальными серверами, к которым имеешь прямой доступ, было одним удовольствием: создание образов, развертывание, восстановление, — все выполнялось моментально. Нужен сервер для тестов — сделал экспорт продакшн сервера и восстановил у себя на компьютере. Быстрая передача данных по локально сети, никаких задержек. Из вне все открывалось тоже достаточно быстро, Yota в обе стороны выдавала 15 мегабит. У большинства до сих пор домашний интернет 1.5 мегабит, не думаю, что можно было заметить разницу. По мне так скорость была еще выше, чем при работе с Amazon Clouds (локальный внутригородской трафик был заметно шустрее).
Проблемой было электричество, иногда его отключали, но в теории это можно было бы решить генератором. ИБП спасали, но ненадолго. По сути этого даже и не замечали, так как отключения происходили крайне редко и в основном ночью. Основной проблемой стало то, что и породило саму идею всего этого, Yota превратилась в унылое Г. Не дожидаясь окончательного падения скорости, я снопа вынес все в Интернет, как оказалось не зря, теперь она уже совсем не та.
Впоследствии сервер, предназначенный под хостинг, стал частью полноценного хостинга с собственной панелью управления на Symfony2, которая через очередь заданий контролирует хостинг-серверы с Java бекендами, на которых находятся сайты клиентов. При увеличении числа клиентов растет число хостинг-серверов, потому нагрузка остается неизменной. Конечно хостинг — это уже избитая тема, но я не удержался. На мой взгляд, решение получилось довольно удобным и экономичным, по крайней мере, мой узкий круг уже существующих клиентов удовлетворен.
P.S.: Статья не писалась специальное под Хабрахабр или Мегамозг, потому, возможно, не совсем подходит по формату. Появился этот текст после очередного доделанного проекта, мой мозг в поисках разрядки решил оглянуться назад и оценить пройденный путь.
© Megamozg