Вступление
Если анализировать другие языки программирования в сравнении с C++, то нельзя явно сказать что C++ хуже других языков.
Проблематика в том, что при неправильном подходе изучения многие люди сдаются и делают единственный вывод в таком ключе: «C++ сложно».
И здесь нужно всё таки задать справедливый вопрос, а это чья проблема? Проблема языка быть сложным (если конечно разработчики языка не преследуют такой цели, чтобы сделать язык специально сложным) или проблема человека, который при совершенно безответственном подходе теряет всю мотивацию к изучению языка?
К сути
C++ сам по себе язык не сложный, вообще любую изучаемую парадигму нельзя называть сложной, потому что вся сложность представляет собой затрачиваемое время на её изучение, для большей простоты, приведу пример.
Допустим человек по имени Д. учится в 5 классе и проходит соответствующий ему курс обучения, и вроде бы всё хорошо. Но теперь представим, что мы человека Д. будем отправлять каждую неделю в разные классы, которые старше изначального (5 класса). И вот он заходит в 9 класс, и ничего не понимает, вот он уже заходит в 11 класс и снова ничего не понимает, и вот он заходит в первый курс любого технического университета и снова ничего не понимает. И что же? Этот человек Д. просто скажет что вся ваша математика сложная наука и изучать я её не буду. А на деле мы просто имеем очень объёмную парадигму, которая состоит из множества других отдельных направлений, что по сути делает её не сложной, увы, а просто объёмной из-за которой кажется что она является сложной. Соответственно ни одну науку нельзя называть сложной, как любую вещь (при изучении/решении), просто либо у человека хватает времени её изучить в систематизированном подходе (от простого к сложному), либо как такого времени и не хватает, потому что рано или поздно любая сложная вещь оказывается простой, лишь по той причине что на основе тех простых вещей человек конструирует представление о сложной.
Как это можно перенести на нашу тему? Легко и просто, C++ это достаточно объёмный язык программирования.
Но человек может его неправильно изучать и вот почему:
Случай 1. Человек осознаёт что придётся изучать достаточно много и делает это не правильно.
Случай 2. Человек не может понять зачем он это делает, и что ему может дать инструмент.
Это две взаимосвязанные вещи между собой, если человек понимает что он хочет от инструмента, то ему нужно подсказать как грамотнее этот инструмент освоить, но если человек изучает инструмент, но не понимает зачем он нужен, то как итог он его поспешно забывает. Вроде бы всё банально и очевидно, но всё таки такие проблемы надо решать.
В первом случае, человеку нужно понять что это совершенно нормально осваивать такую большую парадигму, просто нужно к этому привыкнуть.
(Ибо в сфере IT всегда приходится что-то изучать вне зависимости от языка, деятельности, ибо IT это всегда движение, всегда приходят новые технологии, подходы, идёт развитие и как итог нужно идти в ногу со временем)
Также человеку нужно указать на порядок изучения, хотя при этом существует очень много источников, которые систематизируют весь материал, но при этом не совсем всё и как нужно. Просто здесь могут быть две проблемы, которые человек не разрешил перед изучением:
1. У него не хватает знаний по самой дисциплине (доступим даже тоже строение компьютера, как устроена память, её реализации, информатика и все сопутствующие вещи...). Это просто может породить в его голове вопросы о том, а зачем он изучает C++ или почему там так были устроены вещи, в общем, всё то что может отбить желание при изучении или создать кашу в голове.
2. Попытается изучить что-то наперёд, когда у него не закреплен и не отработан предыдущий материал, как следствие возникают вопросы почему так сложно???
Всё это необходимо устранять и придерживаться следующих советов, которые помогли мне и помогут вам (если хотите можете придумать свой личный подход к изучению, я ни к чему не призываю):
а). Старайтесь устранять все вопросы, которые могут возникать при изучении. То есть вы встретили не понятное слово к примеру «аллокатор» и задались вопросом что это/зачем это/почему это, вы должны ответить на них с помощью проверенных источников информации в виде книг, сайтов, статей и прочее, однако когда вы попытались это разрешить вы встретили что-то ещё не понятное, и здесь самое важное, если вы понимаете, что столкнулись слишком объёмной темой, и так вы изучать будете просто очень много раз, то лучше разбить это на части и вернуться к этому, ну допустим вы поняли зачем нужен аллокатор, но при этом не знаете как устроен оператор «new» или функция «malloc» вы к этому можете вернуться по ходу изучения.
Да мы приходим к тому принципу, что иногда всё таки нужно изучать наперёд или параллельно с изучаемой темой, но не в ущерб пройденному материалу, если понимаете что даётся проблемно, немного сбавьте обороты, отдохните.
Иногда может быть так, что вы изучаете наперёд, но всё равно не понятно, пройдёт время вы сами дойдёте до этой темы имея накопленные знания и сможете уже её понять, и такое может быть, поэтому иногда просто в слепую держите в голове это. 😃
б). Не пытайтесь себя обманывать, что если вы прочитали, то можно спокойно идти дальше - НЕТ! лучше разбирите на примере и ручками начните писать код, чтобы вы досканально поняли как и что работает. Да занимает время, да это нудно, но отчасти вы привыкаете к самой работе программиста, а отчасти вам станет намного яснее, чем вы просто прочитали и пошли дальше.
в). Не пытайтесь изучать тему, если 90% слов вы не понимаете.
Во втором случае, человеку нужно всё таки найти себя и задать несколько вопросов. Что ему ближе? Чего он хочет от жизни? Нравится ли ему-то что он делает в программировании?
Надо ответить всё таки честно, если на первые два выходят неутвердительные, неопределенные ответы, то начните просто пробовать, пробовать разные языки и вообще пытаться заняться чем-нибудь другим, но вы правда должны подсознательно себя оценить и понять, всё таки что же вам условно ближе точные науки или например заниматься творчеством, чем раньше вы с этим разберётесь тем будет лучше для вас, ибо время идёт и оно вас ждать не будет.
Но теперь перейдём к тому, что же будет являться систематизированным подходом, и сможет ускорить ваше изучение/понимание. Вы можете быть не согласны со мной, но после моего пройденного пути, я уже могу делиться с тем, что помогло мне и надеюсь что оно поможет вам:
Инструкция: (материалы будут приложены в самом конце)
1. Изучите сам компьютер (если не знали что это такое)
2. Изучите основы информатики (если не знали что это такое)
2. Изучите строение памяти в компьютере (если не знали что это такое)
3. Изучите «модели» памяти в C++ (если не знали что это такое)
4. Возьмите книгу по C++, но достаточно в строгом изложении (вам придётся к этому привыкать, потому что большинство оперирует как раз таки строго-формальном изложении, так вы сами себя будете приучать к грамотности и будете владеть уже хорошим базисом)
5. Отрабатывайте задания по C++ которые приводятся в книге, если их нет то просто ищите задания в интернете и старайтесь их реализовывать, лучше стремиться решать алгоритмические задачи (но не сразу, для начала вы вообще должны понять как код набирать), и особенно проф. ориентрированные, вам они очень и очень сильно помогут, а также сможете уже заработать достойный минимальный «портфель» для своего работодателя.
6. Никогда не сдаваться
7. Не получилось запомнить, снова повтори
8. Не получилось понять, снова попробуй
9. Пункт номер 6
10. После того как уже вы вроде разобрались с ООП, вроде разобрались с «шаблонами», не старайтесь переходить к изучению многопоточности, ибо вы должны понять более важные вещи, а именно:
- Система управления версиями, какие они бывают (важно)
- Git, Gitlab, может так случится в жизни, что вы пойдёте работать системным программистом и вы будете сидеть на Linux, знайте ваша консоль это второе я, поэтому лучше себя приучайте использовать консоль нежели GUI реализации. (важно)
- Изучить консоль, да и в целом администрирование вашей операционной системы
- Определитесь с code-style или с тем как собственно вас будут понимать и читать ваш код, для этого лучше расширять кругозор по этим самым code-style (важно)
- Паттерны проектирования (важно)
- Изучите best-practices от создателей языка (важно)
- Изучите момент когда лучше использовать try/catch (по усмотрению)
- Определитесь и поймите когда нужно использовать умные указатели (важно)
- Как устроено выравнивание и вообще что это такое (важно)
- Рассмотрите концепцию cache-friendly кода (важно)
- Рассмотрите пример оптимизаций самого языка (важно)
- Попробуйте рассмотреть Assembler (по усмотрению)
- Старайтесь всегда изучать нововыходящие стандарты и вообще понять что такое стандарт языка (важно)
- Изучайте саму OS и её прилагаемый API. (WINAPI для Windows, у Linux "Linux kernel interfaces")
11. Теперь относительно многопоточности:
- Понять как процессор управляет всем этим делом, но перед этим задаться вопросом что такое «поток» и «процесс»
- Межпроцессорное взаимодействие
- По факту многопоточность это то что вы должны «поточить», а соответственно должна быть полнота ваших знаний (ибо что поточить в итоге, если кода нет?)))
- Попробовать реализовать work stealing pool (но и при этом до этого порешать какие-то простые задачки на многопоточность) и после рассмотреть библиотеки для «многопоточности», к примеру TBB, Actor framework, etc.
12. Самое главное смотрите реальные проекты и старайтесь ковыряться в «огромных» (ну или просто в маленьких, но популярных) открытых проектах.
13. Обязательно изучите сети, ибо в 99% случаев вам всё таки придётся с ними работать.
14. Изучайте всё на английском языке, по началу будет очень и очень проблематично даваться, но перейдите в пункт 6. Ибо большинство полезной и актуально-проверенной информации как раз таки располагает зарубежный контингент, однако можно смотреть полезные статьи на проверенных «источниках».
15. Привыкай искать информацию о языке на
данном сайте, потому что если там не можешь найти нужную информацию или уже решение какого-то алгоритма, проблемы - то уже
Google в помощь
16. Старайся писать кроссплатформенный код, то есть понимать что это такое и зачем это нужно.
17. Одно из самых главных вещей после изучения языка программирования, вы должны понимать как анализировать и оптимизировать существующие алгоритмы и системы которые вы получаете, то есть надо
осилить это. Просто эта книга содержит очень и очень хороший материал в достойном изложении. И при этом вы покрываете сами алгоритмы. Также изучите существующие структуры данных, пробуйте сами их реализовать.
18. Уже наверное для продвинутых, рассмотрите известные аллокаторы. Хотя бы два
TBB и
mimalloc.
19. Рассмотрите библиотеку
boost.
20. Задайтесь вопросом почему создавались собственные библиотеки на уровне STL, и почему некоторые разработчики не используют стандартную бибилотеку, а предпочитают что-то другое. (пункт 19)
21. Задайтесь вопросом как ускорить время компиляции и что такое
Single Compilation Unit (смотреть в сторону Unity(Jumbo) Build).
Материалы:
1.
Хорошая книга по изучению C++ 2.
Если вливаться в многопоточность то как начало 3.
Как хорошая книга по многопоточности 4.
Неплохой сайт про статьи о C++ и обзор на книги 5.
Сам Хабр 6.
Собственно Core Guide Lines 7. К вопросу о IDE, но если Windows то
Visual Studio, если Linux то
Qt Creator (бесплатный)/
CLion (лицензия). Если выбрал Linux, то изучи что такое cmake.
8. Очень
хорошая книга по сетям (но не на уровне программирования, а фундаментально)
9. Если вливаться то попробовать изучить
сокеты. Потом копаем в смежном направлении.
10. Для изучения WINAPI
служит как поиск по вашим вопросам, но для более хорошего изучения лучше начать с книги «Чарльз Петцольд Программирование для Windows 95», да сейчас вы можете возразить что старьё, но вы попробуйте и поймёте что она до сих пор актуальна и в то же время может вам дать понять сущность «обратной совместимости».
11.
Что такое процессор 11.2
Дополнение к пункту 11 12.
Что такое память 12.2
Дополнение к пункту 12 13.
Поиск по огромным и не очень большим проектам (Просто пишем C++ в строке поиска и смотрим что понравится душе)
14.
Книга про Алгоритмы и с чем их едят (необходимо осилить)
15. Научитесь искать информацию самостоятельно, это не ирония, а полноценный совет.
16. Научитесь читать много-много различной информации (просто привыкать к этому) - это будет очень полезный навык.
17. Всегда расширяйте кругозор. (Собственно пункт 16)
18. Сидите на ресурсах посвещённой вашей любимой тематике и языку. (Собственно пункт 17)
19. Наверное вспомним «Никогда не сдаваться».
Итоги
Собственно целью моей статьи дать понять начинающим и не очень, что C++ правда не сложный язык программирования, однако он требует внимание к деталям и очень обширные знания. Если вы пройдётесь по всей инструкции и разберетесь со всеми пунктами, то вы будете иметь очень и очень уверенный фундамент для того, чтобы становится хорошим C++ программистом, ровно как и почву для последующего изучения/развития.
Я соглашусь что раздел «материалы» не покрывает все аспекты, но этого хватит для того, чтобы задать мотивации к изучению и задать собственно интерес к широкому поиску.
Да путь достаточно большой, но при всей изложенной информации, вы сокращаете всю дорожку, которые проходили бы люди, которые не обладали такой «инструкцией» и просто копались в интернете ради того, чтобы себя же образовывать вслепую.
Однако не нужно рассматривать данную статью как некую почву для холиваров и о том, какой язык лучше и прочее, моей целью было то, чтобы как можно больше людей влилось в данное направление, и стало одним из достойных членов огромного сообщества C++, чтобы стереть такие понятия как «С++ не для всех», или «Есть программисты которые постигли C++, и которые с этим не справились».
Пусть будет мысль о том что: «C++ для всех, и пусть никто не уйдёт обиженным».
Спасибо за внимание, и уважайте друг друга!