Наноблог Артёма Сапегина

Вероятнее всего новые посты будут выходить только на английском языке.

Заметки о собеседованиях для веб-разработчиков

Довольно беспорядочные советы от настоящего меня прошлогоднему, когда я начинал искать работу в Европе.

Подготовка

  • Обновите резюме и приведите в порядок профиль на Линкедине.
  • Запишите, чем занимались в нескольких последних компаниях. Если собеседование на неродном языке, прочитайте несколько раз вслух (я этого не делал, но после примерно восьмого собеседования понял, что стоило).
  • Походите по сайту компании, посмотрите, какие технологии они используют (насколько это возможно); погуглите техноблог, блог и твитеры сотрудников.
  • Узнайте уровень зарплат в стране. Лучше всего поговорить с кем-то, кто там живёт. Определите подходящую для себя цифру и будьте в ней уверены.

Подумайте об ответах на вопросы вроде:

  • Почему вы выбрали именно нашу компанию.
  • Почему решили уйти с текущего места.
  • Самая сложная задача, какую приходилось решать.
  • Самая интересная задача или проект.
  • Идеальная команда или рабочее окружение.

Сопроводительное письмо

Скорее всего это первое (а часто единственное), что прочитает о вас работодатель. Сопроводительное письмо должно показывать, что вы (и почему именно вы) подходите для определённой вакансии.

Я читаю вакансию, и рассказываю о своём опыте по каждому пункту требований. Если чего-то не знаю, так и пишу. Если был опыт с чем-то похожим (например, спрашивают про Руби-он-рейлс, а я работал с Джанго), так и пишу.

Переписка с айтишными эйчарами и, тем более, самими разработчиками обычно довольно неформальна. Но это вовсе не значит, что можно забыть о грамматике и вежливости. И не забывайте, что ваше письмо будут читать и разработчики, и эйчары: и тем, и другим оно должно быть понятно.

Тестовое задание

Рассматривайте тестовые задания как реальный полезный проект. Так и вам будет полезнее, и будущий работодатель будет видеть, что вы можете не только слепить что-то из джейквери-плагинов, но и писать серьёзный, аккуратный и поддерживаемый код. Именно для этого вас и нанимают, а не чтобы собрать что-то по-быстрому.

Я стараюсь извлечь из каждого тестового задания какую-то пользу для себя — например, попробовать какие-то новые инструменты. Часто это увеличивает объём задания в несколько раз.

Например, я изучал Реакт на тестовых заданиях: первое, второе.

Собеседование

  • Если собеседование по скайпу: оденьтесь, могут позвонить с видео.
  • Не бойтесь говорить «я не знаю» — нельзя знать всё. Можно отвечать: «точно не знаю, но, вероятно, вот так».

Будьте готовы писать код всеми возможными способами:

  • на бумажке;
  • на маркерной доске;
  • в окошке скайпа (высокотехнологичный вариант бумажки);
  • расшарив свой экран через скайп (или наоборот вам дадут доступ к компьютеру);
  • в каком-нибудь онлайновом редакторе с синхронизацией.

Наверняка вам будут показывать кусочки кода и спрашивать, что получится в результате их выполнения. Или будут просить найти ошибку или исправить код, чтобы получить другой результат.

Что почитать

Главное, не начать после всего этого пользоваться полученными знаниями при написании повседневного кода. Всё-таки мы пишем его для людей, и такое ковбойство ни к чему хорошему не приведёт.

Полезные ссылки

  • Grammarly — проверка английского языка.
  • Главред — чистка текста от словесного мусора.
  • Canned Emails — шаблоны писем на все случаи жизни.
  • Codewars — маленькие задачки для программистов.

Сходите на собеседование

Я считаю, что проходить собеседования полезно, даже если вы не собираетесь менять работу. Это позволяет посмотреть на свой опыт со стороны, увидеть свои слабые стороны, и понять, над чем стоит поработать, чтобы стать лучшим разработчиком.

P. S. Буду рад, если поделитесь своими советами.

Работа волнами

Часто бывает: сядешь что-нибудь делать, а оно никак не делается. И так несколько дней подряд, хотя неделю назад всё получалось.

Раньше я расстраивался, когда такое случалось, но потом понял, что такая волнообразность — это нормально.

Когда есть выбор, чего можно фигачить: личные проекты, опенсорс, фриланс и хобби-не-программирование, то становится интереснее. Я заметил, что спады в одних областях часто совпадают с подъёмами в других, и стал этим пользоваться. Если решил пилить фриланс, а прёт обрабатывать фотографии, то я обрабатываю фотографии. Это оказалось гораздо продуктивнее, чем насиловать себя. Желание пилить фриланс всё равно рано или поздно вернётся. (Конечно, это сильно ограничивает выбор проектов, зато остаются самые интересные.)

Хороший пример — профиль на Гитхабе: видно подъём, спад и начало нового подъёма.

Мой профиль на Гитхабе

Как показать графический диалог из шелл-скрипта на маке

Если вы запускаете шелл-скрипт из графической среды (например, из форкфлоу Альфреда), то сообщать пользователю об ошибках и задавать ему вопросы удобно с помощью графических диалогов. Поможет в этом Эплскрипт.

Показываем сообщение об ошибке:

#!/usr/bin/env bash

# error "Сообщение"
function error() {
  osascript <<EOT
    tell app "System Events"
      display dialog "$1" buttons {"OK"} default button 1 with icon caution with title "$(basename $0)"
      return  -- Suppress result
    end tell
EOT
}

error "Not enough cheese!"

Сообщение об ошибке на AppleScript

(Кроме caution можно использовать иконки note и stop.)

Спрашиваем что-нибудь:

#!/usr/bin/env bash

# prompt "Вопрос" "Ответ по умолчанию"
function prompt() {
  osascript <<EOT
    tell app "System Events"
      text returned of (display dialog "$1" default answer "$2" buttons {"OK"} default button 1 with title "$(basename $0)")
    end tell
EOT
}

value="$(prompt 'Enter:' '42')"

Запрос пользователю на AppleScript

Или просто скачайте dlg-error и dlg-prompt, и положите их куда-нибудь в $PATH.

#!/usr/bin/env bash

dlg-error "Not enough cheese!"
value="$(dlg-prompt 'Enter:' '42')"

P. S. Показать уведомление в Центре уведомлений можно с помощью terminal-notifier.

Опенсорса на русском языке не существует

Меня не перестаёт удивлять желание русских разработчиков запереться в своей стране: читать, писать и вести свои проекты только на русском.

Нет причин сознательно ограничивать аудиторию своих проектов, документируя их на русском языке.

Когда-то я решил вести документацию всех своих опенсорсных проектов на английском: (кажущаяся) сложность со временем многократно окупилась.

Небольшой пример: 24 человека прислали код в мой grunt-webfont. Среди них есть американцы, англичане, французы, немцы, шведы, австрийцы, голландцы; а русских всего двое.

Но хуже всего, когда русский разработчик приходит в проект другого русского разработчика, где всё на английском, и начинает рассказывать о своих проблемах на своём родном языке. Это примерно как прислать пулреквест, наплевав на принятый проектом стиль кодирования, но в десять раз хуже. Так вы показываете своё неуважение к автору проекта, ко всем его пользователями и разработчикам, которые могут не знать русский язык, но, в отличии от вас, не поленились выучить английский.

Я уже подумываю начать закрывать любые задачи и пулреквесты с описанием не на английском в своих проектах: удобство большинства пользователей важнее удобства нескольких лентяев.

Когда будете заводить на Гитхабе свой следующий баг или пулреквест, опишите его на языке проекта. Скорее всего это будет английский. Автор и пользователи проекта будут вам благодарны.

Когда будете публиковать свой следующий опенсорсный проект, напишите документацию и комментарии в коде на английском. Так вы во много раз увеличите его возможную аудиторию.

Как не ослепнуть в интернете

Часто бывает: заходишь к кому-нибудь в блог, а там вот такое:

Микроскопический шрифт

Всё так мелко, что прочесть нельзя.

Поможет плагин для Хрома Zoom Text Only. Несколько раз нажимаем Alt+плюс и спокойно читаем текст:

Можно прочитать

Но иногда это не помогает, ведь автор может испортить не только шрифт, но и сделать фон тёмным (скриншоты можно кликать):

Тёмный фон

Или не задать максимальную ширину страницы:

Оооооочень длинные строки

Тут поможет плагин Clearly. Включаем, и глаза больше не болят:

Красота

Bower: зачем фронтенду нужен менеджер пакетов

Статья впервые была опубликована в майском номере журнала Хакер. В журнал вошла сильно сокращённая версия; ниже — полная.

Менеджеры пакетов упрощают установку и обновление зависимостей проекта, то есть сторонних библиотек, которые он использует: jQuery, Fotorama, всё, что используется на вашем сайте и написано не вами.

Хождение по сайтам библиотек, скачивание и распаковка архивов, копирование файлов в проект — всё это заменяется парой команд в терминале.

У многих языков программирования есть стандартные менеджеры пакетов, которыми разработчики пользуются для установки всех библиотек: gem у Руби, pip у Питона и другие. У серверного Яваскрипта есть npm (почему он не подходит для клиентского — ниже), а у клиентского яваскрипта до недавнего времени ничего не было. Было множество разных пакетных менеджеров (Jam, Component, Volo, Ender), но большинство из них так и не стали популярными, а от менеджера пакетов, которым не поставишь нужных библиотек, толку мало.

Бовер — не стандартный менеджер пакетов для клиентского Яваскрипта, но самый популярный: сейчас там больше 11 тысяч пакетов.

Бовер не навязывает пользователю свою систему сборки, а разработчику пакетов — метод подключения библиотеки (AMD, CommonJS и другие). Всё, что делает Бовер — устанавливает нужные проекту пакеты подходящих версий вместе с их зависимостями. Другими словами: просто загружает файлы нужных библиотек и всё, что нужно для их работы в специальную папку. Остальное остаётся на усмотрение разработчика.

Почему не npm

Главное отличие npm и Бовера — подход к установке зависимостей пакетов. npm устанавливает зависимости для каждого пакета отдельно, в итоге получается большое дерево пакетов (node_modules/grunt/node_modules/glob/node_modules/…), где может быть несколько версий одного и того же пакета. В клиентском Яваскрипте это недопустимо: нельзя подключить на страницу две версии jQuery или любой другой библиотеки. В Бовере каждый пакет устанавливается один раз (jQuery всегда будет в папке bower_components/jquery, сколько бы пакетов от него не зависело) и в случае конфликта зависимостей, Бовер просто не станет устанавливать пакет, не совместимый с уже установленными.

Установка Бовера

Для работы с Бовером вам потребуются Node.js и Git. Установка:

npm install -g bower

Работа с пакетами

Попробуем что-нибудь установить, например, jQuery:

bower install --save jquery  # Или bower i -S jquery

Эта команда скачает jQuery последней версии в папку bower_components/jquery.

Флаг --save говорит Боверу, что он должен сохранить имя пакета и его версию в файл-манифест — bower.json. В этом файле хранится список всех зависимостей проекта (пакетов, установленных через Бовер) и другие метаданные, нужные для создания своих пакетов (об этом в конце статьи). Вместе с именами пакетов можно указать версии, с которыми ваш проект гарантированно будет работать.

У нас такого файла ещё нет, о чём и говорит строчка «No bower.json file to save to, use bower init to create one» в логе. Создадим его:

bower init

Бовер будет задавать много вопросов, но до тех пор пока мы не захотим зарегистрировать свой пакет, ответы на большинство из них не имеют значения, можно просто нажимать Enter.

На вопрос «set currently installed components as dependencies?» нужно ответить «Yes» — все ранее установленные компоненты (в нашем случае это jQuery) автоматически попадут в созданный JSON-файл. А на вопрос «would you like to mark this package as private which prevents it from being accidentally published to the registry?» — тоже «Yes» — это предотвратит случайную регистрацию пакета в реестре Бовере.

Поставим ещё несколько пакетов:

bower install --save social-likes jquery-icheck fotorama

И посмотрим, что у нас получилось:

bower list
bower check-new     Checking for new versions of the project dependencies..
bowertest#0.0.0 /Users/admin/bowertest
├─┬ fotorama#4.5.1
│ └── jquery#2.1.0 (2.1.1-beta1 available)
├── jquery#2.1.0 (2.1.1-beta1 available)
├─┬ jquery-icheck#1.0.2
│ └── jquery#2.1.0 (2.1.1-beta1 available)
└─┬ social-likes#3.0.2
  └── jquery#2.1.0

Команда bower list показывает список всех установленных пакетов. Тут мы видим, что все пакеты зависят от jQuery, и что Бовер смог найти подходящую всем версию — jQuery 2.1.0.

На файловой системе это выглядит вот так:

tree -L 2
.
├── bower.json
└── bower_components
    ├── fotorama
    ├── jquery
    ├── jquery-icheck
    └── social-likes

5 directories, 1 file

Каждый пакет устанавливается в свою папку, вложенных пакетов нет, jQuery встречается только один раз. В корне проекта лежит созданный командой bower init файл bower.json, но теперь там перечисленны уже все пакеты, которые показывает bower list, а не только jQuery.

Для удаления пакетов используется команда bower uninstall:

bower uninstall --save jquery-icheck  # Или bower un -S jquery-icheck

Вы можете спокойно удалять папку bower_components или добавить её в ваш .gitignore. Команда bower install (без дополнительных параметров) вернёт всё как было:

bower install

Развёртывание проекта

Есть два подхода к развёртыванию проектов:

  1. В репозиторий добавляется только файл-манифест и все пакеты устанавливаются во время развёртывания проекта. Так в репозитории не хранится ничего лишнего, но если во время развёртывания упадёт Гитхаб или другой сервер, с которого устанавливаются пакеты, будут проблемы.
  2. В репозиторий добавляется не только bower.json, но папка bower_components. Так развёртывание не зависит от внешних серверов, но репозиторий раздувается десятками (а то и сотнями) лишних файлов.

Семантические версии (semver)

Semver — это, во-первых, подход к версионированию библиотек: формат номера версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ и правила, по которым следует увеличивать то или иное число.

А во-вторых — это способ описания требуемых версий зависимостей, который используют Бовер и npm.

При установке с флагом --save версии пакетов добавляются в bower.json в виде ~1.0.1. Тильда в начале говорит о том, что при установке будет выбрана версия 1.0.1 или с большим последним числом (ПАТЧ), если она есть. Таким образом будет установлена версия с последними исправлениями ошибок, но полностью совместимая с той, что указана в файле-манифесте.

Обновление зависимостей

В Бовере есть команда bower update, но она обновляет пакеты с учётом требований файла-манифеста. Например, если там указан jQuery ~2.0.0, то Бовер сможет обновить jQuery до версии, скажем, 2.0.9, но 2.1.0 уже не поставит, потому что эта версия не соответствует формуле ~2.0.0.

Для обновления пакетов (и bower.json) до действительно последних версий можно воспользоваться утилитой bower-update. Устанавливаем:

npm install -g bower-update

Запускаем:

bower-update

Поиск пакетов

Есть два способа найти пакет в Бовере: гиковский и обычный.

Гиковский:

bower search jquery
Search results:

    jquery git://github.com/jquery/jquery.git
    jquery-ui git://github.com/components/jqueryui
    ...

Обычный: открыть в браузере bower.io/search.

Автоматическая сборка

Бовер перекладывает проблемы сборки установленных пакетов на плечи разработчика. Самый простой способ — просто склеить JS-файлы Грантом, Галпом или любой другой системой сборки, которой вы пользуетесь.

Я пользуюсь Грантом, поэтому расскажу, как склеивать пакеты Грантом. О том как пользоваться Грантом была большая статья в июльском номере прошлого года, поэтому покажу сразу конфиг плагина grunt-contrib-concat:

concat: {
  main: {
    src: [
      'bower_components/jquery/jquery.min.js',
      'bower_components/fotorama/….js',
      'bower_components/jquery-icheck/….js',
      'bower_components/social-likes/social-likes.min.js’,
      'scripts/*.js'  // Скрипты вашего сайта
    ],
    dest: 'build/scripts.js'
  }
}

У этого способа есть много недостатков: вам нужно смотреть имена файлов для каждого пакета; следить, чтобы файлы собирались в правильном порядке (например, jQuery должен быть выше, чем скрипты, зависящие от него). Плагин grunt-bower-concat может делать это сам: он автоматически склеивает все установленные зависимости в правильном порядке в один файл:

bower_concat: {
  all: {
    dest: 'build/_bower.js',  // Склеенный файл
    exclude: [  // Пакеты, которые нужно исключить из сборки
        'jquery',  // Если jQuery подключается с CDN Гугла
        'modernizr'  // Если подключаем скрипты в конце страницы; Modernizr нужно подключать в <head>
    ]
  }
},
concat: {
  main: {
    src: [
      'build/_bower.js',
      'scripts/*.js'  // Скрипты вашего сайта
    ],
    dest: 'build/scripts.js'
  }
}

Регистрация своих пакетов

Чтобы ваша библиотека стала доступна для установки через Бовер, её нужно зарегистрировать. Для этого:

  • В корне проекта должен лежать файл-манифест bower.json.
  • У проекта должен быть гит-репозиторий (например, на Гитхабе).
  • Проект должен использовать семантические версии и в репозитории должен быть гит-тег для последней версии.

Для создания файла файла-манифеста снова воспользуемся командой bower init:

bower init
[?] name: awesomelib
[?] version: 0.0.1
[?] description: My awesome jQuery plugin.
[?] main file: jquery.awesomeplugin
[?] keywords: jquery awesome yay
[?] authors: Artem Sapegin <artem@sapegin.ru>
[?] license: MIT
[?] homepage: https://github.com/sapegn/jquery.awesomeplugin.js
[?] set currently installed components as dependencies? Yes
[?] add commonly ignored files to ignore list? Yes
[?] would you like to mark this package as private which prevents it from being accidentally published to the registry? No

{
  name: 'awesomelib',
  version: '0.0.1',
  description: 'My awesome jQuery plugin.',
  main: 'jquery.awesomeplugin.js',
  keywords: [
    'jquery',
    'awesome',
    'yay'
  ],
  authors: [
    'Artem Sapegin <artem@sapegin.ru>'
  ],
  license: 'MIT',
  homepage: 'https://github.com/sapegn/jquery.awesomeplugin',
  ignore: [
    '**/.*',
    'node_modules',
    'bower_components',
    'test',
    'tests'
  ],
  "dependencies": {
    "jquery": "~2.1.0"
  }
}

[?] Looks good? Yes

И хотя обязательно нужно заполнить только имя пакета (поле name), остальные поля тоже очень полезны:

  • description и keywords помогут пользователям найти вашу библиотеку через интерфейс поиска пакетов.
  • main определяет главный файл пакета. Это поле может быть использовано автоматическими сборщиками, такими как grunt-bower-concat.
  • license — всегда указывайте лицензию: она говорит потенциальному пользователю вашего пакета, сможет ли он использовать его в своём проекте. Например, лицензия GPL требует, чтобы любой использующий её проект тоже распространялся по этой лицензии, что не всегда возможно.
  • ignore — по умолчанию Бовер скачивает весь репозиторий, что, во-первых, увеличивает время установки, а, во-вторых, добавляет в проект лишние файлы. Лучше всего исключить всё, кроме необходимых для работы пакета файлов (главный JS-файл, CSS и так далее), лицензии и ридми.
  • dependencies — все пакеты, от которых зависит ваш пакет.

Теперь нужно закоммитить bower.json, создать гит-тег с последней версией и запушить всё в удалённый репозиторий:

git add bower.json
git commit -m "Add bower.json."
git tag "v0.0.1"
git push origin --tags

Вот теперь можно регистрировать пакет:

bower register jquery-awesomeplugin git://github.com/sapegin/jquery-awesomeplugin.git

Дальше Бовер сам будет проверять обновления пакета, главное не забывать создавать гит-тег для каждой новой версии.

Для облегчения обновления своих пакетов можно воспользоваться такими инструментами, как grunt-bump или mversion.

Мультиязычный блог на DocPad

Я веду этот блог на двух языках, но технически это один сайт на Докпаде, из которого собираются HTML-файлы на разных языках.

Вы можете посмотреть исходники блога, а я расскажу, как сделать так, чтобы у вас тоже был блог на нескольких языках.

Перевод постов

Создадим отдельные папки для постов каждого языка. В моём случае это src/documents_en и src/documents_ru (для русского и английского языков).

И добавим вот такой код в конфиг Докпада (docpad.coffee):

docpadConfig = {
  ...
  environments:
    en:
      documentsPaths: ['documents_en']
      outPath: 'htdocs_en'
    ru:
      documentsPaths: ['documents_ru']
      outPath: 'htdocs_ru'
  ...
}

Теперь можно собирать блог на нужном языке:

docpad run --env en  # Запустить локальный сервер с английской версией
docpad generate --env ru  # Собрать русскую версию

Перевод интерфейса

Создадим YAML-файлы для каждого языка. Например, src/lang/en.yml:

lang: en
url: http://blog.sapegin.me
title: Artem Sapegin’s Blog
poweredBy: Powered by <a href="{dp}" class="link">DocPad</a>
visibleTags:
  - tools
  - html
  - css
tagNames:
  tools: Tools
  html: HTML
  css: CSS

Сюда можно поместить всё, что должно зависеть от языка блога.

Нам так же понадобятся несколько функций, добавим их в конфиг Докпада:

YAML = require 'yamljs'
moment = require 'moment'
_ = require 'lodash'

pluralTypes =
  en: (n) -> (if n isnt 1 then 1 else 0)
  ru: (n) -> (if n % 10 is 1 and n % 100 isnt 11 then 0 else (if n % 10 >= 2 and n % 10 <= 4 and (n % 100 < 10 or n % 100 >= 20) then 1 else 2))

docpadConfig = {
  templateData:
    ...
    # Локализованная дата
    pubDate: (date) ->
      moment(date).format('LL')  # December 23 2013

    # Перевод строки
    # Вернёт исходную строку, если перевод не будет найден
    # Есть простейший шаблонизатор: @_ 'Lorem {num} ipsum', num: 42
    _: (s, params=null) ->
      params ?= []
      s = @site[s] or s
      s.replace /\{([^\}]+)\}/g, (m, key) ->
        params[key] or m

    # Числительные: @plural(3, 'dog|dogs')
    plural: (n, s) ->
      ((@_ s).split '|')[pluralTypes[@site.lang](n)]

  events:
    generateBefore: (opts) ->
      # Достаём текущий язык из окружения Докпада
      lang = @docpad.getConfig().env
      # Загружаем строки для нужного языка
      strings = YAML.load("src/lang/#{lang}.yml")
      _.merge(@docpad.getTemplateData().site, strings)
      # Настраиваем языка для Moment.js
      moment.locale(lang)

    ...
}

Установим библиотеки, которые использовались в предыдущем отрывке кода:

npm install --save-dev yamljs moment lodash

Правила преобразования числительных можно найти в polyglot.js.

Теперь нужно заменить в шаблонах все зависящие от языка данные на вызовы функций @_, @plural и @pubDate.

Обычные строки:

<a href="/about"><%= @_ 'About' %></a>
<%- (@_ 'poweredBy', dp: 'http://docpad.org/') %>

Числительные:

<%= @_ '{num} {posts}', num: documents.length, posts: @plural(documents.length, 'post|posts') %>

И даты:

<%= @pubDate @document.date %>

Переключатель языка

Добавим несколько новых строк в YAML-файлы:

transLang: ru
transUrl: http://nano.sapegin.ru
translation: По-русски

И ещё одну функцию в docpad.coffee:

docpadConfig = {
  templateData:
    ...
    # URL текущей страницы на другом языке или главной страницы, если для текущей страницы нет перевода
    translationUrl: ->
      if fs.existsSync "src/documents_#{@site.transLang}/#{@document.relativePath}"
        "#{@site.transUrl}#{@document.url}"
      else
        @site.transUrl
    ...
}

Ну и, собственно, ссылку в шаблон:

<a href="<%= @translationUrl() %>"><%= @_ 'translation' %></a>

Настройка сервера

Последнее, что нужно сделать, — это настроить веб-сервер так, чтобы он отдавал файлы нужного языка при заходе на соответствующую версию блога (у меня это отдельные домены, но можно сделать и разные директории), но это уже выходит за рамки этого поста.

P. S. Другой подход к созданию мультиязычного блога на Докпаде.

Нельзя просто взять и сделать блог на английском

Рома Комаров призывает разработчиков писать по-английски. Меня в его посте смущает только один момент: где он советует не бояться за свой плохой английский. Бояться, конечно, не нужно, но кому-то может показаться, что качество текста вообще не важно, а это не совсем так. Но об этом в другой раз.

У меня главная трудность с английским не в боязни писать что-то на чужом языке, а в ощущении бесполезности.

На RSS моего англоязычного блога подписано ровно ноль человек. У твитера 93 читателя: из них треть — русские, треть — боты, и только треть — настоящие живые иностранцы.

Поэтому мне очень трудно заставлять себя что-то туда писать.

Сейчас я пишу скорее для изучения языка. Да и, если ничего не писать, то читатели точно не появятся.

Наверное, надо просто продолжать стараться, и лет через пять — десять читатели появятся, как это было с моими русскими блогами.

Опенсорс для всех

Помочь опенсорсному проекту может каждый. Для этого совсем не обязательно уметь программировать и быть гуру консоли. В опенсорсных проектах есть не только код, но и, например, документация. А во многих проектах — книгах или словарях — кода нет вовсе.

Но не все знают, что это можно сделать не выходя из браузера.

Находите на Гитхабе нужный файл (нужно быть залогиненым) и нажимаете кнопку Edit:

GitHub: редактирование файла

Редактируете и сохраняете файл.

Сразу после сохранения Гитхаб предложит отправить пулреквест:

GitHub: отправка пулреквеста

Описываете ваши изменения и нажимаете кнопку Send pull request.

Всё, вы сделали мир чуть-чуть лучше.

Читайте меньше технических книг

Владимир Старков советует читать больше одной технической книги в месяц. А я считаю, что нужно вообще поменьше читать технических книг.

Понятно, что нужно следить за происходящим в отрасли, но для этого лучше всего подходят блоги и твитер.

Чтение для меня — не только получение знаний, но и удовольствие от процесса. А для этого книга должна быть хорошо написана. Из авторов технических книг редко получаются хорошие писатели, и часто такие книги просто скучные.

Есть множество интересных вещей кроме языков программирования и новых фреймворков. Например, я люблю читать книги о фотографии (тоже нетехнические), дизайне, типографике, языке, людях и других вещах.

К сожалению, у меня самого пока плохо получается следовать собственному совету — технических книг всё равно большинство, а художественных почти совсем нет.

И главный совет — почаще выбирайтесь из офиса с хорошей нетехнической книгой.