Обратите, пожалуйста, внимание, что этот текст последний раз обновлялся в 2015 году и в некоторых местах может быть устаревшим.
За всё время работы в области веб-разработки так и не увидел хорошего вводного текста, объясняющего новичкам что к чему, вводящего в предметную область. Человек, решивший заняться разработкой сайтов (к примеру), должен побираться по гуглу в поисках крох информации. Единственное, что можно найти, это различного качества материалы вида «HTML и JavaScript за 2 часа», или «Введение в PHP и MySQL». Всё это есть плохо.
Веб — это совокупность стандартов, соглашений, подходов, которые не ограничиваются и не определяются языками программирования или каким-то конкретным софтом. Что бы нормально работать в этой области (как и в любой другой), необходимо ориентироваться в принципах на которых она построена.
Поэтому в этом тексте не будет программного кода, примеров конфигурации софта и прочей ерунды.
Вместо этого будет максимально лаконично представлена информация о том, что в принципе можно ожидать от технологии веба, что в нём можно делать и каким образом это можно делать. Любые пояснения, по возможности, будут даваться в виде ссылок на википедию и аналогичные ресурсы (прочтение материалов по ссылкам очень желательно обязательно). Ссылки даются на русскоязычные ресурсы, но в некоторых случаях следуют обращаться к их англоязычным аналогам (например, английской википедии), так как они содержат больше информации.
Данный «учебник» отражает ситуацию с моей колокольни и не претендует на объективность и охват всей области веб разработки. По поводу исправления ошибок или дополнений смело связывайтесь со мной любым удобным вам способом.
Перед дальнейшим чтением убедитесь, что вы знаете, что такое клиент, сервер и браузер.
Традиционно выделяют несколько сфер ответственности в веб-разработке:
Рассмотрим подробнее каждую часть и процесс их взаимодействия. Но сначала…
Любые взаимодействия программных компонент осуществляются не просто так, а по протоколам. Протокол — это договорённость между несколькими сущностями о том, как и что должно происходить при их совместной работе. Нас, в первую очередь, будут интересовать протоколы передачи данных.
Основной протокол для веб-разработчика — HTTP. По нему, например, браузеры запрашивают страницы сайтов. Но этим его применение не ограничивается.
Кроме HTTP, полезно знать о существовании других протоколов:
Протоколы передачи данных принято делить на уровни. Протоколы более высокого уровня работают с помощью протоколов более низкого уровня. Например HTTP обычно работает поверх TCP.
Когда мы вбиваем в браузере адрес страницы, наш компьютер не шлёт запрос напрямую серверу, на котором находится сайт. Этот процесс более сложен:
Отображая страницу пользователю, браузер имеет дело со следующими типами информации:
Обработка страницы начинается ещё во время загрузки. В частности, по мере загрузки HTML кода:
Загружая страницу, браузер строит представление документа в виде DOM, которым может оперировать JavaScript и на которое распространяется влияние CSS стилей.
Поведение страницы (включая выполнение JavaScript кода) управляется событиями. В частности, события шлются по таким поводам, как окончание загрузки страницы, картинки или нажатие на ссылку.
В обработке запроса пользователя на стороне сервиса (например, сайта) может участвовать более одной машины, поэтому называть всю инфраструктуру «сервером» не совсем корректно.
В общем случае, обработка запроса пользователя будет происходить в следующем порядке (в реальных проектах некоторые пункты могут отсутствовать):
HTTP — HyperText Transfer Protocol — протокол передачи гипертекста.
Для ознакомления с темой желательно прочитать минимум статью на википедии, а лучше соответствующие RFC для разных версий протокола:
Что необходимо знать:
Один из самых важных нюансов веб-разработки это (в общем случае) то, что:
Поэтому в обязательном порядке следует руководствоваться следующими правилами:
Следствием этих правил являются ограничения, касающиеся различных аспектов веб-разработки. Например:
Сюда же можно отнести различные проблемы с соблюдением негласных соглашений между клиентом и сервером: негарантированность соблюдения форматов передачи данных (вплоть до различия в разделителях дробной и целой частей в числах), расхождение в значениях (например, время у клиента и сервера может отличаться и непредсказуемо изменяться).
Следует обратить внимание на тип взаимодействия программного сервера непосредственно с кодом обработчиков. Современные версии серверов обычно загружают код один раз (например, при обработке первого запроса), поэтому необходимо следить, чтобы данные от старого запроса не влияли на обработку нового (запросы могут быть от разных пользователей!).
Во время обработки типичного запроса клиента к серверу возникает масса задержек:
Задержки влияют не только на удовлетворённость пользователя, от них также сильно зависит производительность вашего сервера (количество обрабатываемых запросов в единицу времени).
Бороться с задержками можно разными способами:
Сервер может одновременно обрабатывать несколько запросов, как от разных пользователей, так и от одного. Поэтому необходимо постоянно помнить о проблемах параллельной обработки данных:
Необходимо следить за работой систем, ответственных за хранение данных на стороне сервера (системой кэширования, базой данных, файловой системой). В частности надо помнить, что:
Большим преимуществом веб-приложений является возможность их обновления сразу у всех пользователей — для этого достаточно обновить сервер.
Но следует помнить, что это влечёт за собой также и возможность сломать ПО сразу у всех клиентов, скомпрометировать их личную информацию или просто уничтожить все их данные (что практически ведёт к потере бизнеса и это в лучшем случае).
Защититься от этих проблем помогут следующие практики:
Ещё одной важной особенностью веб-приложений является скачкообразная нагрузка на сервера. Количество клиентов, одновременно использующих ваш сервер может зависеть от времени дня, поры года, фазы луны, праздников, различных непредвиденных событий, работы ваших пиарщиков и, конечно, DoS атак.
Поэтому ПО должно проектироваться не из расчёта на среднюю нагрузку, а с учётом возможных скачков этой нагрузки в несколько раз (а то и на несколько порядков). Помните, что если вам «повезёт», то Вы можете столкнуться со Слэшдот-эффектом (или «хабра-эффектом», что ближе к рунету).
Исходя из-этого соображения следует управлять и физическими ресурсами (мощностью серверов и прочим).
При этом не обязательно ставить целью полную работоспособность ПО на максимальной нагрузке, важно чтобы пользователи знали что оно работает и ничего «страшного» не происходит.
Обычные средства противостояния скачкам нагрузки включают:
Как упоминалось ранее, весь процесс обработки типичного http запроса можно условно разделить на несколько этапов:
Необходимо помнить, что это абстрактные этапы обработки абстрактного запроса. Часть из них может отсутствовать либо пересекаться (например проверка прав и сбор/обработка данных могут идти одновременно). Кроме того, на любом из этапов обработка запроса может завершиться ошибкой или возвращением закэшированного ответа.
Выполняется на основании всех данных запроса: пути, параметров запроса, его типа, заголовков.
Включает в себя три этапа:
На каждом следующем этапе возрастает сложность правил, по которым обрабатывается запрос. Балансировщик нагрузки распределяет запросы на основе их базовых свойств (или просто обеспечивает примерно равную нагрузку на каждый физический сервер), программные сервера определяют то, каким образом должен обрабатываться запрос (в основном выбор идёт между отдачей статического файла и вызовом специализированного кода), фреймворк обрабатывает запрос пользуясь непосредственно логикой определяемой предметной областью.
Прежде чем предпринимать какие-либо действия, необходимо убедиться, что субъект, запрашивающий их, обладает необходимыми правами доступа. Права пользователя могут распространяться как только на конкретный объект, так и на группу или тип объектов.
Один из возможных наборов прав:
Часть прав обычно является следствием отношения владения между пользователем и объектом (например, автор статьи владеет ей и поэтому имеет права на редактирование и удаление) или административной должности пользователя (например, модератор форума может удалить даже чужую тему).
Обычно наиболее ресурсоёмкий этап, так как данные не располагаются прямо в коде, а хранятся в сторонних хранилищах (файловая система, база данных, кэш). Подключение к каждому из них и последующие запросы занимают существенное временя, так как хранилища подчиняются собственной логике и одновременно взаимодействуют с множеством других процессов. Следует учитывать следующие моменты:
В большинстве случаев обработка данных не требуется (например, если просто надо отобразить страницу) или почти не требуется (обновить или создать запись в базе данных).
Но в некоторых случаях необходимо выполнить какой-либо сложный алгоритм. Например, создать картинку, или посчитать статистику. В этом случае необходимо всегда помнить о времени выполнения этого алгоритма. Если оно может быть велико, или требует большого количества ресурсов (по сравнению с другими запросами), то следует перенести его выполнение в фон (возможно даже на другую машину). Пользователю в этом случае можно сообщить о том, что задача начала выполняться, а получить её результат он может отдельным запросом. Конечно, это не обязательно доводить непосредственно до пользователя, достаточно реализовать нужное поведение на JavaScript.
Игнорирование запросов, отбирающих на себя большое количество ресурсов чревато существенными задержками в обработке всех остальных запросов. А при большом количестве пользователей возможна ситуация, когда несколько подобных задач будет вызвано одновременно (на самом деле такая ситуация гарантирована), что может полностью остановить работу сервера.
Ответ (html-текст или данные в другом виде) можно подготовить к отправке несколькими способами:
В большинстве случаев в ответ на запрос по конкретному адресу достаточно отдавать данные в строго определённом формате (например, на запрос HTML-страницы возвращать только HTML). Но протокол HTTP позволяет клиенту указывать желаемый формат возвращаемых данных (с помощью заголовка Accept), опираясь на который сервер может выбирать между разными форматами.
При отправке ответа к нему также имеет смысла добавить несколько HTTP-заголовков, указывающих на формат и кодировку возвращаемых данных, особенности кэширования, и другие моменты. «Хорошие» фреймворки многие из заголовков устанавливают автоматически.
В общем случае база данных — это совокупность структурированных данных и связей между ними представленная в форме, удобной для обработки вычислительной техникой. Следует отличать понятие базы данных и системы управления базами данных: если 1-я — это набор данных, то 2-я — это программные средства, для работы с этими данными.
Существует большое количество разных типов баз данных, но в общем случае их можно разделить на два типа:
Кроме того, в областях, связанных с искусственным интеллектом, любят говорить о базах знаний, но это скорее характеристика хранящихся в них данных или подхода к работе с ними, а не типа базы или её структуры.
Далее, если не будет указано явно, речь пойдёт о реляционных БД.
Схема БД — это описание содержания, структуры и ограничений базы данных.
Индекс — это объект СУБД, специальная структура данных, хранящая отношение <ключ, указатель на запись> и предназначенная для ускорения поиска и доступа по ключу. «Правильные» индексы позволяют значительно ускорить обработку запросов к СУБД.
Транзакция — группа последовательных операций, представляющая собой логически целую единицу (иными словами, частичное выполнение такой последовательности операций не имеет смысла). Является одним из ключевых понятий при работе с базами данных.
В зависимости от СУБД требования к транзакциям могут варьироваться. Одним из наиболее распространённых наборов требований является ACID:
Ещё одним требованием выступает целостность данных, которая по смыслу является более узким понятием, чем согласованность и не включает в себя бизнес-логику (см. пример с переводом денег в банке).
Нормальная форма — это свойство схемы данных в реляционных БД, характеризующее её с точки зрения избыточности (которая может приводить к логическим ошибкам при выборке или изменении данных). Всего выделяют 6 нормальных форм.
Нормализация — это процесс приведения схемы БД в нормальную форму. Её задача — уменьшить логическую избыточность (а значит и количество потенциальных ошибок). При этом влияние на производительность СУБД или объём занимаемых данных может быть любым. Чрезмерное увлечение нормализацией может отрицательно сказаться на производительности или сложности восприятия алгоритмов обработки данных. Поэтому в некоторых случаях нормализацию специально уменьшают.
В процессе разработки могут изменяться как схема БД, так и её содержимое. Этими изменениями необходимо управлять, чтобы при обновлении проекта не произошло непредвиденных эффектов. Механизм, организации таких изменений называется миграциями.
Миграция — это программный код, который при своём выполнении производит необходимые изменения в схеме БД или в её данных. Для удобства обычно вводят понятие версий БД или версий таблиц БД, в этом случае миграция обеспечивает преобразование БД из версии N в версию N+1 (или наоборот).
Миграции делятся на:
Рекомендуется на каждое изменение делать оба типа миграций, так как никто не защищён от непредвиденных обстоятельств.
Также миграции делят на:
Важно помнить, что код миграций нельзя привязывать к коду проекта (например, ссылаться на методы, объявленные в нём), т.к. код проекта изменяется, в то время как миграции должны оставаться неизменными. Если не следить за этим, то в определённый момент может измениться логика одной из функций (или функция просто будет удалена), используемых миграцией, и она станет нерабочей (и будет «ломать» БД при своём применении).
Кэш — промежуточное хранилище с быстрым доступом, предназначенное для временного хранения информации, получение которой связано с существенно большей тратой ресурсов, чем чтение её из кэша. Позволяет существенно сократить использование вычислительных ресурсов.
Под получением информации может пониматься как непосредственно получение (например, чтение из реляционной БД), так и выполнение любого другого ресурсоёмкого алгоритма (например, получение миллионного простого числа).
Обычный алгоритм использования:
Обычно данные помещаются в кэш на время, после чего удаляются из него, это позволяет поддерживать актуальность информации в кэше (т.к. в нём хранится только их копия) и гарантируется, что они устареют не более, чем на указанное время жизни. Чаще всего, данные помещаются в кэш по уникальному строковому ключу.
В вебе кэширование может применяться на всех этапах обработки запроса:
Когда данные пропадают из кэша (по истечении времени жизни или вытесненные более важными), следующая попытка получить эти данные приведёт к выполнению «тяжёлого» кода. Следствием этого может быть:
Для сглаживания проблемы можно использовать несколько подходов:
В некоторых случаях может понадобится очистить часть кэша (очистить весь просто), но перебирать все ключи крайне затратно.
Для этого можно в ключ, по которому сохраняются данные, добавить их версию. Например: some_data_1, other_data_1.
Когда нам надо «удалить» данные some_data и other_data, мы увеличиваем номер версии и по новым ключам (some_data_2, other_data_2) данных уже не будет. Старые данные удалятся, когда истечёт их время жизни.
Сессия — это процесс обмена сообщениями (диалог) между устройствами или между пользователями и устройствами. Сессия имеет начало, конец и может включать обмен более чем одним сообщением в каждом из направлений. В контексте этой статьи мы будем говорить о сессии между пользователем (его браузером) и веб-сервером (сайтом).
Как указывалось ранее, протокол HTTP не предполагает сохранение состояния между запросами, из-за чего приходится либо передавать всю необходимую информацию вместе с каждым запросом либо организовывать сессии.
В этом случае сервер, при первом обращении нового пользователя, создаёт у себя хранилище данных, доступное по уникальному идентификатору, который и передаётся между запросами. Идентификатор обычно хранится в cookies. За счёт этого появляется возможность несколькими путями управлять длительностью сессии:
В сессии обычно хранятся результаты аутентификации (идентификатор пользователя, если тот «вошёл» на сайт), различная статистика и дополнительная информация, которую допустимо утратить в случае потери сессии. Важные данные хранить в сессионном хранилище нельзя:
Наиболее удобным подходом к хранению сессионных данных, с точки зрения соотношения производительность/надёжность, является использование базы данных с дублированием информации в кэше. Так как изменение данных происходит достаточно редко, обращений к базе практически не происходит (что ускоряет обработку запросов), в то же время гарантируется сохранность данных.
Следует помнить, что злоумышленник может получить доступ к сессии пользователя, получив её идентификатор (например, перехватив один из запросов с ним). Поэтому, для проведения всех важных операций (изменение пароля/почты, оплаты, удаления аккаунта) необходимо требовать явного подтверждения от пользователя (например, ввода пароля).
Следует различать несколько важных понятий:
Аутентификация — процедура проверки подлинности, например: проверка подлинности пользователя путём сравнения введённого им пароля с паролем в базе данных.
Авторизация — предоставление определённому лицу или группе лиц прав на выполнение определённых действий; а также процесс проверки (подтверждения) данных прав при попытке выполнения этих действий.
Идентификация — процедура, в результате выполнения которой для субъекта идентификации выявляется его идентификатор, однозначно идентифицирующий этого субъекта в информационной системе.
Таким образом, при «входе» пользователя на сайт, происходят следующие операции:
Обратите внимание, что OpenID позволяет проводить аутентификацию пользователя, а OAuth — только авторизацию на произведение определённых действий.
На текущий момент существует большое число проверенных временем (и людьми) компонент, которые мы можем смело использовать в разработке. Поэтому всё чаще «узким местом» в безопасности становится непосредственно разрабатываемый сервис.
При разработке всегда следует помнить, что самый надёжный код — это код, который не написан, а самый надёжный способ хранить данные — это не хранить их.
Наиболее частые ошибки, приводящие к «дырам» в безопасности:
Существует большое количество типов атак, вот наиболее распространённые:
Внедрение кода — использование ошибки в обработке входящих данных, для внедрения вредоносного кода на ресурс.
В обоих случаях, достаточно эффективной защитой является либо экранирование специальных символов, либо полное их удаление. 3. CSRF — Сross Site Request Forgery — подделка межсайтовых запросов — при посещении пользователем сайта злоумышленника, от имени пользователя автоматически шлётся запрос на атакуемый ресурс. Если пользователь авторизован на нём и запрос не требует подтверждения, то он будет выполнен без ведома пользователя. Для защиты от этой атаки можно: - требовать подтверждения всех важных операций; - проверять заголовок HTTP_REFERER, если он указан в запросе; - ассоциировать с сессией пользователя секретный ключ и требовать его явное указание в каждом запросе. Например, хранить его в cookies (которые шлются автоматически и не доступны злоумышленнику) и требовать его передачу в качестве параметра во всех запросах, тогда проверка происходит сравнением этих параметров. 4. Перехват данных — атака, при которой злоумышленник получает возможность просматривать все данные, передаваемые по открытым каналам. В частности, могут быть перехвачены логин/пароль, идентификатор сессии и прочая приватная информация. 5. Человек посередине — атака, при которой злоумышленник подключается к каналу между клиентом и сервером и тем самым получает возможность просматривать и редактировать сообщения между ними, оставаясь незамеченным. При этом клиент может считать злоумышленника сервером, а сервер — клиентом. 6. DoS-атака — Denial of Service — отказ в обслуживании — атака создающая условия, при которых пользователи системы не могут получить доступ предоставляемым ей услугам (обычно, вследствие большой нагрузки на сервера).
Многие современные фреймворки (и другие компоненты) уже имеют проверенные средства защиты от большинства видов атак, поэтому, по возможности, следует использовать их. Собственная реализация защиты потребует существенного времени и может оказаться нефункциональной из-за любой допущенной ошибки.
Следствием требований безопасности также являются ограничения, касающиеся различных аспектов веб-разработки. Например:
Довольно часто недобросовестные пользователи пытаются получить выгоду от автоматизации взаимодействий с вашим сервисом. Выражаться это может в написании ботов для игры, скриптов для рассылки спама, подборе паролей к аккаунтам пользователей и подобных вещах. Для защиты от таких действий существует несколько подходов:
Для того, чтобы разрабатываемый нами продукт приносил пользу, он должен быть доступен пользователям. А значит он, как минимум, должен:
Хостинг — услуга по предоставлению вычислительных мощностей для размещения информации на сервере, постоянно находящемся в сети.
Условно, можно выделить несколько видов хостинга:
Независимо от типа хостинга, каждый из них в той или иной степени может быть реализован «в облаке», что, в частности, даёт дополнительные возможности по масштабированию сервиса.
Сторона, предоставляющая услуги хостинга, обычно также обеспечивает бесперебойную работу инфраструктуры (например, подачу электричества), выдаёт статический IP адрес.
Отдельно стоит указать на важность использования CDN — Content Delivery Network — сетевой инфраструктуры для оптимизации доставки контента пользователям. Распространение контента с помощью CDN позволяет как ускорить доставку данных пользователям, так и существенно сократить непрофильную нагрузку на сервера.
IP-адрес — уникальный сетевой адрес узла в компьютерной сети, построенной по протоколу IP (по этому протоколу работает большинство сетей, в том числе и интернет). IP-адрес имеет каждое устройство, подключённое к интернету.
В большинстве случаев предоставляется вместе с хостингом (с возможностью докупать дополнительные адреса). На текущий момент идёт переход с формата адресов IPv4 на IPv6.
DNS — компьютерная распределённая система для получения информации о доменах. В нашем случае она интересна в первую очередь из-за возможности автоматического получения IP-адреса по читаемому имени. Именно эта система обеспечивает нахождение веб-ресурса по имени вроде «wikipedia.org».
Приобрести доменное имя можно в одной из множества компаний, занимающихся их регистрацией. После приобретения Вы должны получить доступ к редактированию файла dns зоны, в котором можно указывать соотношения доменных имён и IP-адресов, а также некоторые другие параметры.
Прописав в настройках зоны IP-адрес нашего сервиса, мы сделаем его доступным по соответствующему доменному имени.
Следует помнить, что DNS — иерархическая структура, узлы которой обновляют информацию с определённой периодичностью, поэтому информация о соотношении доменного имени и IP-адреса не обновляется мгновенно (и может задерживаться на несколько часов).
Мониторинг — процесс непрерывного наблюдения и регистрации состояния объекта. В нашем случае — веб-проекта.
Следить необходимо за всеми хоть сколь-нибудь важными параметрами (конечно, по возможности) и выявлять аномалии в их поведении. В конечном счёте, качество работы проекта хорошо характеризуют два параметра:
Любые технические проблемы в Вашем проекте так или иначе скажутся на одном из этих параметров.
Развертывание ПО — все действия, связанные с подготовкой к использованию ПО. Включая, но не ограничиваясь: установку (как целевого ПО так и сопутствующего), обновление, конфигурацию.
Процесс развёртывания не менее важен, чем сама разработка, так как при неверном проведении может полностью перечеркнуть все труды разработчиков (например, уничтожив данные в БД). Это операция периодическая (необходимо делать при каждом обновлении) и достаточно однообразная, поэтому особенно подвержена ошибкам из-за человеческого фактора. Как следствие, её необходимо максимально автоматизировать и документировать. На текущий момент для этого есть достаточно средств. В идеале, обновление или установка ПО должны запускаться одной простой командой (скриптом), не требующей ввода дополнительных данных.
Кроме того, необходимо убедиться, что специалист, ответственный за эту операцию, в курсе всех необходимых вопросов как со стороны разработки так и со стороны администрирования.
При использовании кэширования, при обновлении проекта следует учитывать следующие нюансы:
Front-end — часть проекта (и сфера ответственности), связанная с его клиентской составляющей. Это непосредственно веб-страницы, отображение информации пользователю и получение команд от него.
На каждой веб-странице можно выделить статическую и динамическую составляющие.
Статическая составляющая страницы, обычно состоит из:
Часто этого достаточно для того, чтобы получить полезный информационный ресурс, например личный блог. Тем более, сейчас существует большое количество сторонних сервисов, берущих часть функционала на себя, например, организацию комментариев.
Для удобства работы с CSS было разработано несколько мета-языков, список которых можно найти среди ссылок в конце текста.
Если от ресурса (веб-страницы) требуется организовать сложное поведение, то его описывают на JavaScript (в подавляющем большинстве случаев). Для этих скриптов браузер предоставляет окружение и API для манипулирования содержим страницы (атрибутами узлов DOM, стилями). Разработка на JavaScript в основном событийно-ориентированная, существует возможность «вешать» обработчики как на действия пользователей (например, клик мышью по ссылке), так и на независимые от него события (например, окончание загрузки страницы).
Скрипты могут быть как прямо встроенными в страницы, так и загружаться отдельно.
В контексте управления веб-страницей JavaScript можно назвать достаточно низкоуровневым ЯП. Поэтому разработано большое число вспомогательных библиотек, упрощающих рутинные операции.
Из-за множества нюансов, связанных с безопасностью, при выполнении кода скриптов браузеры вводят ограничения на некоторые типы действий (Same Origin Policy), часто довольно неприятные, но необходимые.
AJAX (Asynchronous JavaScript and XML) — подход к построению интерактивных веб-страниц, заключающийся в фоновом обмена данными с сервером (т.е. без перезагрузки страницы).
При правильном использовании позволяет улучшить реакцию пользовательского интерфейса (сгладив задержки вызванные загрузкой большого объёма данных, например, можно по клику на название книги загружать её обложку, не загружая сразу все обложки) и просто сделать его удобнее, реализовав дополнительную реакцию на действия пользователя (например, подгружать подсказки при вводе пользователем поискового запроса).
Существует несколько подходов к реализации взаимодействия с сервером из JavaScript:
Когда проект запущен, необходимо сделать так, чтобы потенциальные пользователи его могли найти. Не касаясь прямой рекламы, рассмотрим базовые механизмы работы поисковых сервисов.
Каждая поисковая система постоянно с помощью «пауков» (поисковых роботов) пробегает по всем доступным ей веб-страницам, анализируя информацию, расположенную на них. Задача разработчиков сделать всю необходимую информацию доступной для пауков, по возможности, в удобном для них виде и так, чтобы по определёнными поисковым запросам сайт находился в выдаче на максимально высокой позиции.
SEO (Search Engine Optimization) — комплекс мер для поднятия позиций сайта в результатах выдачи поисковых систем по необходимым запросам пользователей.
Для достижения этой цели можно проводить следующие мероприятия:
Кроме того, следует помнить, что поисковые системы значительно лучше воспринимают статические сайты, чем динамические.
Сравнение популярных фреймворков
Список заготовленных наборов стилей для быстрого внедрения стандартного и целостного дизайна на сайт.
Недавно в одной из дискуссий на gamedev.ru удалось удачно сформулировать своё видение текущего состояния и тенденций рынка MMORPG в области игровых механик. Поскольку давно хотел написать про это дело, то не премину развить мысль.
Разговор пойдёт про «классические» MMORPG: WoW, SWTOR, Rift — все, которые претендуют на массовость, имеют общий игровой мир и признаки ролевой игры.
Главный посыл следующий: жанр в упадке. Не с финансовой точки зрения, конечно. И не с точки зрения «успешности». Деньги обсуждать не будем, только механики.
Этот текст развивает идеи предыдущего моего поста «MMOG в которую я хотел бы играть»
Привет.
В посте Тесты, которые тестируют тесты я описал свой взгляд на верификацию программ через дублирование их логики в виде отдельной модели и последующее сравнение с ней. В качестве частного случая выступили юнит-тесты.
В этот раз, опираясь на изложенные идеи, я попробую сформулировать общий подход к оценке уровня верифицированности ПО.
Сначала я хотел назвать этот текст «Зачем нужен бизнес-план», но к чему себя ограничивать? План — он и в Африке план, не важно для чего. Тот, что для бизнеса, называется бизнес-планом. Тот, что для эвакуации, называется, как ни странно, планом эвакуации. И так далее.
Но идея текста таки пришла из области, где актуальны бизнес-планы. Часто стал встречаться с высказываниями о том, что «бизнес-план, конечно, нужен, но вот конкретно в нашем случае он пользу не принесёт потому, что»:
Сам я тоже страдал этими тараканами, но так получилось, что периодически разного рода планы составлять всё-таки приходилось. И хочу вам сказать — планы делать полезно и нужно.
Но сначала…
Животрепещущий вопрос, не правда ли?
Меня уже 3 года как им пытают персонально, поэтому я решил попытаться рассказать всё-таки почему. Рассказывать, конечно, буду со стороны разработчика-одиночки. В командах побольше есть некоторые нюансы, но суть та же.
Для затравки приведу небольшую иллюстрацию, смысл её, думаю, понятен.