О чём эта статья


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

image


Для кого предназначена данная статья


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

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

Предисловие


Хотя информационные технологии в наши дни очень развиты, их освоение и становление квалифицированным профессионалом продолжает оставаться тяжёлым. Автор, будучи тренером-инструктором сделал несколько попыток найти своим студентам наиболее удобный путь освоения программирования и относящихся к этому тем. Данная статья является попыткой построения простой структурированной картины данной проблематики.

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

Автор начал использование языка C# с самого времени его создания. До этого времени автор получил богатый опыт в работе со множеством ИТ технологий – аппаратурой, внутренними особенностями ОС, языком Assembler, C++, COM, WinApi, сетями, многопоточностью, и т.п… Полученные навыки существенно помогли осваивать язык C#, .NET Framework, а также их новые версии. Но для новичков обучение требует от них также изучения множества новых технологий из различных незнакомых сфер, что делает изучение долгим и тяжёлым процессом.

Наибольшая трудность


Наибольшая трудность, возникающая при изучении чего-либо – огромное количество различных технологий, а также секторов промышленности, где эти технологии могут быть применены. Также данное количество постоянно увеличивается (смотрите так называемую «технологическую сингулярность»).

Ориентация в такой сложной среде становится очень трудной. Простые правила, объяснение и стратегия были бы очень полезны.

Человек, Инструмент, Проблема


Для понимания многих важных процессов и элементов системы обучения может использоваться связь Человек-Инструмент-Проблема.

Для удобства анализа проблемы примем следующие допущения:
  • Человек – главное действующее лицо. Человек использует Инструмент для решения Проблемы. Человек должен обладать необходимыми навыками для того, чтобы использовать Инструмент;
  • Проблема – главная задача для Человека – она требует решения;
  • Инструмент – это средство для решения Проблемы. Каждый инструмент разрабатывается для решения только специфических проблем. То есть нет Инструмента, способного решать все проблемы. Язык программирования – это тоже Инструмент, предназначенный для решения проблем создания Программного Обеспечения;
  • В течении решения Проблемы Человек не взаимодействует с ней напрямую, а посредством Инструмента (Подразумевается что Инструменты делают взаимодействие Человека с Проблемой легче чем прямое взаимодействие Человек-Проблема. Если подобный инструмент не существует, его следует создать).


Сложность Проблемы и Инструмента


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

Для упрощения объяснения мы можем рассматривать сложность проблемы только лишь как сложность её решения. Сложность инструмента в свою очередь может рассматриваться как сложность его использования человеком. Чем проще инструмент тем проще человеку его использовать.

Для решения одной проблемы могут использоваться различные инструменты. По удобству использования Инструменты могут быть распределены по группам:
  • Наиболее полезные – лёгкие в использовании решающие сложные проблемы;
  • Средние — сложные в использовании решающие сложные проблемы;
  • Бесполезные – сложные в использовании решающие простые проблемы.


Сложность Использования


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

Сложность чего-либо для человека может быть классифицирована следующим образом:
  • Слишком большое множество простых элементов. Эти простые элементы очень просты и требуют сложной композиции для для решения проблемы. Языки низкого уровня, такие как Assembler или MSIL – примеры языков с подобным типом сложности. Этот уровень сложности наиболее удобно реализовать аппаратно, так как аппаратура способна выполнять огромное количество относительно простых действий;
  • Малое количество элементов с малым количеством свойств. Это наиболее удобный для человека уровень сложности. К этому уровню можно отнести базовые элементы языков высокого уровня;
  • Элементы со слишком большим количеством свойств. Инструменты этого уровня сложности предназначены для решения узкого круга задач и требуют настройки если задача немного отличается. Пакеты программного обеспечения и библиотеки могут быть отнесены к этому уровню сложности.


Низкий, Высокий и Сверх-высокий Уровни



Эволюция языков программирования привела к росту уровня абстракции языков программирования от аппаратной платформы:
  1. Языки низкого уровня – удобны для реализации аппаратурой, но сложны для человека ввиду большого количества команд, выполняющих простейшие операции;
  2. Языки высокого уровня – удобны для понимания человеком, что позволяет разрабатывать программы быстрее. Но эти языки сложны в реализации для выполнения аппаратурой, что приводит в общем случае к получению более медленного кода и большему потреблению ресурсов;
  3. Языки сверх-высокого уровня (very high-level programming language, VHLL) — языки программирования с очень высоким уровнем абстракции. В отличие от языков программирования высокого уровня, где описывается принцип «как нужно сделать», в сверхвысокоуровневых языках программирования описывается лишь принцип «что нужно сделать».


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

Но для корректного использования во избежание негативных побочных эффектов разработчику необходимо знать внутреннее устройство конструкций. Так при использовании в сетевом приложении сокетов необходимо знать соответствующие сетевые протоколы и принципы работы сетей. Без их понимания маловероятно написать в действительности качественный продукт. То есть повышение уровня абстракции просто прячет сложность внутри, но не избавляет от неё.

Эволюция языков программирования показывает их постоянное усовершенствование, но за долгое время развития не упростила их понимания. Здесь следует также упомянуть что существенно расширился круг проблем, решаемых ИТ – поэтому они и остаются сложными.

Эта эволюция – не простой процесс. Однако некоторые особенности могут помочь понять этот процесс:
  • Эволюция аппаратных платформ даёт возможности роста всего сектора ИТ;
  • Рост возможностей сектора ИТ позволяет применять эти технологии для решения всё более сложных и сложных проблем;
  • Сложные проблемы могут решаться только инструментами, имеющими внутреннюю сложность, но простыми в использовании. (Если инструмент сложный в использовании – в нём нет необходимости);
  • Внутренне-сложные инструменты более сложны в создании (чем внутренне простые);
  • Сложность языков программирования отражает сложность поставленных задач.


Сложность языков программирования


Сложность современных языков программирования явилась результатом следующих главных факторов:
  • Многопоточность. Наблюдается постоянный рост параллелизма выполнения команд, поддерживаемого всё большим количеством устройств. Это требует дополнительных сил на синхронизацию потоков и использования ресурсов;
  • Сложные компоненты в стандартных библиотеках. Наблюдается постоянный рост компонентов, встраиваемых в стандартные библиотеки и имеющие большое количество свойств. Необходимо знание как устроены эти компоненты внутри для избежания отрицательных побочных эффектов;
  • Поддержка многоплатформенности. Наблюдается постоянный рост ассортимента устройств и платформ, требующих обеспечения правильного поведения программы на как можно большем количестве устройств. Это особенно явно наблюдается для мобильных приложений;
  • Эволюция. На определённый язык программирования влияют развитие других языков, развитие аппаратуры и даже коммерция (новая версия – новый продукт для продажи на рынке).


Языки Сверх-высокого Уровня


Описанные процессы эволюции языков программирования привели к появлению больших компонентов с большим количеством свойств. Развитие языков высокого уровня происходит на основе языков низкого уровня (например используется компиляция с языка высокого уровня на низкий уровень) путём интеграции малых компонентов (команд) в более крупные конструкции. Помимо прочего описанные процессы имеют инерцию, которая в итоге переводит язык программирования с высокого уровня далее — на так называемый Сверх-высокий.

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

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

image


Стратегия


Начальный уровень


Наиболее простой для изучения программирования уровень – это уровень где количество компонентов и свойств этих компонентов удобно для понимания разработчиком. Обычно эти компоненты отражают простые популярные операции – арифметические операции, обработку строк текста, ввод/вывод простых данных и т.п. Большинство книг начинают повествование именно с этого уровня.

На начальной стадии наиболее важно понимание вопроса – «а что далее ?» Это – ключевой тактический вопрос, позволяющий видеть своё развитие от текущей точки дальше. Вопрос «а что далее ?» может возникать в двух важных случаях:
  • Разработчик сталкивается с проблемой непонимания темы или метода (проблема застревания) или;
  • Разработчик сталкивается с проблемой того, что имеется большое количество тем, которые можно изучать (проблема выбора).


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

После освоения начального уровня разработчик может сделать выбор дальнейшего развития в двух основных направлениях:
  • Низко-уровневое программирование;
  • Высоко-уровневое программирование.


Низко-уровневое программирование


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

Низко-уровневое программирование — это специфическое напривление. Разработчик должен сам принять решение следования этому направлению. Это также направление, в настоящее время редко выбираемое разработчиками.

Высоко-уровневое программирование


Высоко-уровневое программирование – программирование, с помощью которого обычно создаётся программное обеспечение, автоматизирующее крупные процессы жизнедеятельности человека. Оно нацелено на решение прикладных проблем, не заботясь об оптимизации работы аппаратуры.

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

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

Организация


Описанные выше проблемы не являются неразрешимыми. Однако если не предпринимать правильных действий, можно зайти в тупик. Многие действия известны и ясны. Представленное выше описание позволяет понять эффективность и необходимость этих действий:
  • Специализация. Так как освоить все возможности современного языка программирования, имеющихся компонентов и библиотек невозможно, специализация позволяет выбрать только одно или несколько направлений (например настольные приложения, сетевые приложения, библиотеки функций, и т.п.) и работать только с ними;
  • Кооперация. Решение многих задач одним разработчиком невозможно ввиду специализации (как было описано невозможно одному специалисту владеть широким рядом технологий). Таким образом возникает следующее необходимое действие – кооперация с разработчиками, владеющими другими технологиями.


Рекомендации


Подводя итоги можно выделить следующие важные факты:
  • В само-развитии и профессиональном росте необходимо знание направления желаемого развития – к более высоко уровневым (более абстрактным) языкам программирования или задачам, близким к платформе/аппаратуре (например системное программирование или программирование систем реального времени);
  • В случае застревания при изучении определённой темы нельзя останавливаться – нужно или изменить способ изучения этой темы или начать другую тему, отложив текущую до лучших времён;
  • В случае выбора также нельзя останавливаться – нужно просто сделать выбор. И ни в коем случае нельзя пугаться того, что тем много и всех их освоить не удастся;
  • Не следует ставить целью изучение широкого круга тем, т.е. нужно специализироваться, выбрав определённый ряд тем;
  • Даже в освоении программирования кооперация очень важна. Следует общаться с другими разработчиками и участвовать в форумах.


И главное — без любви к программированию и желания трудиться изучить программирование и стать профессионалом не удастся.Даже при отсутствии таланта упорством можно достичь некоторых результатов и найти своё место в широком спектре ИТ.
Поделиться с друзьями
-->

Комментарии (8)


  1. vilgeforce
    03.06.2016 18:41

    «Поддержка многозадачности.» — вообще это задача ОС. Синхронизация потоков, кстати, тоже может решаться средствами ОС…


    1. dgakh
      03.06.2016 20:03

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

      Я заменил «Поддержка многозадачности.» на «Многозадачность.» для большей ясности.


      1. aminought
        06.06.2016 08:12

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


  1. michael_vostrikov
    03.06.2016 21:23
    +8

    Какая-то скучная и бессмысленная лекция из универа. Половина капитанских советов, вторая половина непонятная или явно неправильная. Постоянно встречаются упущения нужных деталей "для упрощения объяснения".


    Для человека наиболее важна простота использования инструмента.

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


    Эволюция языков программирования привела к образованию двух групп

    Это не 2 самостоятельные группы. Языки высокого уровня образовались из языков низкого уровня. Это следующий уровень абстракции.


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

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


    путём интеграции малых компонентов (команд) в более крупные

    Это называется создание функции или библиотеки. Языки более высокого уровня создаются для более высокого уровня абстракции, в первую очередь абстракции от железа/ОС. И это не приводит к повышению сложности языков программирования, как раз наоборот. PHP считается более простым, чем C++.


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

    Я тоже могу нарисовать рисунок, где будет видно совершенно обратное.


    Если кто-либо начинает изучение программирования, он/она делает это с какой-либо целью, например для устройства на хорошо оплачиваемую работу. Эта цель может быть ответом на вопрос «а что далее ?».

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


    1. dgakh
      03.06.2016 21:36
      +4

      Большое спасибо за Ваш детальный комментарий. Мне действительно приходится работать со студентами и хотелось найти ответы на некоторые вопросы. Я не ожидал множества положительных оценок за эту статью и хотелось больше вопросов и критики. Спасибо Вам за уважение к моему труду — Вы не просто поставили минус, но дали довольно объёмный отзыв! Я завтра пересмотрю статью с учётом Ваших комментариев. Ещё раз спасибо!


  1. Crandel
    04.06.2016 08:47
    +1

    А мне понравилась статья, хорошо систематизирует базовые вещи, полезно для программистов-самоучек


    1. dgakh
      04.06.2016 10:49

      Большое спасибо за положительный отзыв. Вы правы — она собственно и ориентирована на программистов-самоучек. Ибо если программист сам не захочет учиться, насильно из него можно сделать только оператора.
      Откровенно говоря я её начал писать давно и опубликовал по принципу что лучше пусть опубликую как есть чем будет валяться в ожидании доведения до совершенства. Тем более хорошая критика укажет явные промахи. Буду ломать мозги чтобы выбросить из неё лишнее и описать кое что яснее чтобы она была понятнее и полезнее большему числу читателей. :-)


    1. Fedcomp
      07.06.2016 23:14
      -1

      Едва ли, сухой материал очень плохо усваивается. Излишняя формализация.