>> |
No.4864
Файл: that_very_feel_you've_sought_so_long.png -(2385 KB, 1920x1080, that_very_feel_you've_sought_so_long.png)
>>4829
>>4853
>>2033
Мне кажется, что приобретение общих писательских навыков можно разбить на два класса:
- Быстрое написание эффективного, компактного, элегантного кода;
- Создание хорошей архитектуры.
-
Первое хорошо развивается решением задачек на алгоритмы и структуры данных на строготипизированном процедурном языке без исчерпывающего количества фич и без привязки под конкретную архитектуру вычислителя, а также постоянным программированием. Находить задачки можно на сайтах для школьников https://informatics.mccme.ru/ . Можно ещё искать их (и участвовать в соревнованиях) на более серьёзных сайтах, например - https://codeforces.com/ , https://atcoder.jp/ .
Стоит, однако, упомянуть, что часть алгоритмов, рассматриваемых на сайтах для школьников (да и студентов), подразумевают некий абстрактный вычислитель (который на деле ни разу не абстрактный) со случайным доступом к памяти (который есть, но на порядок медленнее последовательного), с последовательным выполнением команд и прочей неправдой. Поэтому на деле они не применяются. Так в strstr (в glibc) отнюдь не КМП и не Ахо-Карасик, про которые вроде обычно рассказывают в российских учебных заведениях. А strchr делает отнюдь не простой побайтовый перебор, и где-то в 10 раз быстрее тривиальной реализации оттого.
Второй класс навыков можно и нужно развивавть написанием чего-то серьёзного и useable-ного. Решением реальных (в частности - своих) задач. В случае полного отсутствия знаний и навыков, вполне можно сразу переходить к чему-то реальному, но тут есть риск наделать много глупостей, на которые в случае отсутствия стороннего review'ера будет некому указать. Это не всегда критично. Чем больше практики написания кода - тем проще и лучше будет получаться.
Ещё нужно отметить более узкий набор навыков: знание целевого языка и его библиотек, понимание принципов их устройства, умение ими пользоваться без гугла. В случае с C, например, можно просто сделать свою реализацию стандартной библиотеки, основав её на каком-нибудь открытом ядре (например, Linux). По крайней мере, в некоторых школах для взрослых людей, рассказывали, это входит в процесс обучения.
В случае полного отсутствия навыков я бы предложил такой алгоритм обучения:
1. Задачки на алгоритмы и структуры данных на C.
2. Написание на C разных игрушечных программ, задействующих особенности архитектур вычислителей и бегущих на них систем с целью их изучения. Можно тронуть исходный код стандартных библиотек. Можно тронуть современный ассемблер (например, GNU'шный) и низкоуровневые средства отладки по типу GDB, посмотреть, во что компилируется код более высокоуровневых языков в зависимости от параметров и прошагать скомпилированное. Можно поиграться с каким-нибудь открытым ядром и его основными подсистемами.
3. После этого можно серьёзно заняться хоть современным C++, хоть модно-молодёжными Go и Rust, хоть Python.
Тут будет полезно понимать принципы реализации высокоуровневых фич языков и систем, и осознавать то, какие проблемы эти языки решают (или добавляют). Например, отсутствие наследования - переопределения методов в C контрится возможмостью делать структуры, содержащие ссылки на функции для работы с данными; это более долгий способ, но иногда большая гибкость такого подхода бывает нужна. Наличие try/catch в языке в большинстве случаев убирает необходимость пользоваться goto в ситуацииях, когда после каждой ошибки надо выгружать нарастающее по ходу метода количество загруженных ресурсов; так в Java goto де-факто нет. Если бы в Java можно было указатели на функции, то не было бы нужды делать (анонимные) классы, единственное преднозначение которых - унаследоваться от класса-слушателя события и переопределить метод для его обработки. Наличие метаданных и reflex'ии в C# позволяет на ходу делать метапрограммирование: особенно помогает от повторения аннотаций данных и кучи строк кода типа table.columns["somevar"][i] = obj[i].somevar. В языках без таких возможностей оно частично решаться препроцессором и отдельными программами, разворачивающими дескрипторы и файлы в кучу строк кода на момент компиляции.
|