elizarov


Блог Романа Елизарова


Previous Entry Share Next Entry
Языки которые должен знать программист: Си
elizarov

Я писал о том, что программист должен знать несколько языков программирования. Теперь я конкретизирую какие именно языки должны быть известному каждому программисту. Начну с языка программирования Си. Согласно индексу TIOBE, язык Си является самым популярным языком программирования уже очень продолжительное время. Он иногда уступает первую позицию, но в общем стабильно держится первым.

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

По сути, язык Си это переносимый макроассемблер современности. Язык Си позволяет решать задачи на уровне абстракции, который максимально приближен к железу. В нем нет никакого скрытого поведения за исключением макропроцессора. Каждая инструкция языка транслируется в машинный код прямым и понятным образом. Исполняется ровно тот код, который программист видит на экране. Это естественным образом способствует написанию быстрого кода без лишних накладных расходов. Ведь для того, чтобы код написанный на Си работал медленно, выполняя какие-нибудь лишние операции, вызовы этих лишних операций явным образом запрограммировать.

Зачем же нужно знание языка Си программисту, который пишет прикладное программное обеспечение на других языках? Во первых, все первые пять наиболее популярных сейчас языков программирования так или иначе основаны на языке Си. В дополнение к самому Си на первом месте, C++ и Objective-C являются его расширениями в том или ином виде, а Java и C# используют синтаксис основанный на языке Си.

Во вторых, если программист пишет на каком-нибудь узкоспециализированном или универсальном динамическом языке (PHP, JavaScript, Python, Perl и т.п.), то его среда исполнения, интерпретатор, и основные библиотеки в большинстве случаев написаны на Си (ну или иногда на C++, что не отменяет необходимость знать Си). А значит для того, чтобы понять что же именно происходит в том или ином куске кода, почему та или иная операция занимает какое-то определенное время или потребляет какие-то ресурсы нужно иметь представление о языке Си. Любая нестандартная ситуация или неожиданное поведение — и вот уже приходится изучать исходные тексты библиотеки на Си. Любой выход за рамки задач, которые были предусмотрены разработчиками языка — и вот уже приходится самому писать расширение на языке Си. Собственно, все универсальные языки программирования поддерживают тот или иной способ взаимодействия с кодом написанным на Си, что подчеркивает особый статус языка Си в современном мире.

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

Язык Си это лингва франка современного программистского мира. Хотите, чтобы ваши идеи были понятны наибольшему число программистов? Изложите их на языке Си или, на крайний случай, на одном из Си-подобных языков. Хотите понимать максимальный круг литературы, написанной для программистов про алгоритмы, дизайн и т.п.? Учите язык Си.

UPDATE: В догонку про C++.


  • 1

Я бы учил программистов так...

Соглашусь, с одним дополнением:

1. Lisp
2. C and a little bit of assembly
3. C++ but not too much
4. Python/Ruby
5. R/S/MatLab

Java в этом списке нет специально, потому что никаких новых концепций она не вводит. Человек, владеющей этим списком, начнет писать на Java в течение 15 минут.

Re: Я бы учил программистов так...

Тема, а Лисп специально, чтоб потрахаться? Вероятность, что лисп может хоть как-то поднадобится находится где-то в эпсилон-окрестности нуля ;)

Re: Я бы учил программистов так...

Я сказал "программистов", а не "кодеров". :) Хороший программист все что "может понадобиться" сам освоит. Как сделать из нормального человека хорошего программиста - вот в чем вопрос. :)

Вкратце rationale такой (описание того, чему учит каждый пункт):

1) What programming actually is
2) How it actually really works
3) What objects actually are (just a lot of function pointers, mostly)
4) How it is mostly done nowadays
5) How to do math on computers


Re: Я бы учил программистов так...

Интересно, а что значит, что Python/Ruby это "How it is mostly done nowadays"? Это работа в Google так изменяет сознание человека, что появляется ощущение что все пишут на Питоне?

Re: Я бы учил программистов так...

Большинство Web-startup'ов в Силиконовой долине пишутся на Питоне или Руби. Даже не-Web стартапы используют Питон или Руби очень часто. Java ненавидят почти все. В последнее время модно все писать на JavaScript, что тоже очень мило. Есть еще Scala и Clojure, но это меньше.

Я, конечно, не спорю, что если пойти работать программистом в банк или в отдел операционных систем в Microsoft, то будет много Java, C и C++.

Но Python/Ruby считаются одними из самых прогрессивных языков. И, кстати, самые близкие к Lisp из популярных. :)

P.S. Мир мобильных приложений - это пока еще Java и Objective C. Но я думаю, через несколько лет их динамические языки вытяснят.

Re: Я бы учил программистов так...

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

Любовь к Питону в Силиконовой долине (как и неожиданный рост популярности Си в ~2005-2006 году) это краткровременное икривление простанства вызванное компанией Гугл. Такое ощущение, что после её успешного IPО все в долине подумали, что для успеха обязательно всё делать именно так, как в Гугл, включая использование именно тех языков, которые наиболее популярны в Гугл. Да и в силу её размера, почти каждый стартап там сделан бывшими сотрудниками Гугла или их знакомыми.

Тут очень показателень язык Dart, который разрабатывается в недрах Гугл. Видно, что искревление пространства в самом Гугл особенно сильно. Доставляет возможность языка опускать описание типов всюду, при том что "An emerging pattern is to add types to interfaces and method signatures, and omit types inside methods".

Про динамические языки в целом я тоже как-нибудь напишу. Их милая особенность в том, что мода на них очень скоротечна. Ведь их в основном используют для проектов типа "написал и забыл", таких как большинство web-cайтов.

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

Re: Я бы учил программистов так...

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

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

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

Если тебе интересно, что мне есть сказать по этому поводу, я с удовольствем все распишу. А если ты хочешь просто поспорить, у меня, к сожалению, нет времени. Вывод о том, что ты подходишь к диалогу не объективно, а полемично, я сделал исходя из того, что ты совершенно опустил тот факт, что я написал Python/Ruby, а не просто Python.

Просто для примера, ошибки, которые ты совершаешь:

1) Google имеет очень опосредованное отношение к популярности Python
2) Python появился в 1991 году
3) Огромное количество софта написано на Python, включая больше сайты, например, Quora, Reddit, оригинальный YouTube, Washington Post, NASA, PBS.
4) Огромное количество сайтов написано на Ruby on Rails, например, Groupon и GitHub.
5) Сам Google практически весь frontend пишет на Java.
6) Google почти ничего не пишет на C - только C++.
7) Google почти ничего не пишет на Ruby.
8) Динамические языки - это не просто динамическая типизация. Динамические языки восходят к семейству Lisp и к ним также относятся (в разной степени) Smalltalk, Objective C, JavaScript, Perl, PHP и проч. Про "мода скоротечна" это ты, конечно, загнул.
9) ...и еще много фигни какой-то, например, про безумный размер Google.

В целом ощущение такое, что ты совсем не разбираешься в том, о чем говоришь, no offense.

Ссылки для познавательного чтения:

http://en.wikipedia.org/wiki/Python_(programming_language)
http://en.wikipedia.org/wiki/List_of_Python_software
http://webmasters.stackexchange.com/questions/1342/are-there-any-large-web-sites-written-with-python-django
http://en.wikipedia.org/wiki/Ruby_on_Rails
http://en.wikipedia.org/wiki/Type_system#Dynamic_typing
http://en.wikipedia.org/wiki/Dynamic_programming_language

Artem.

Re: Я бы учил программистов так...

Спасибо за ссылки. Я сознательно не упомянул про Ruby. Его не будет в моем списке языков которые надо знать каждому программисту. Rails это действительно отличный каркас. Однако, без потери общности, можно сказать что популярность Ruby обусловлена популярностью Rails. В то время как область применения Питона намного шире чем web сайты на Django. Я в курсе что Питон появился в 1991 году, но рост его популярности удивительным образом коррелирует с IPO Гугла.

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

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

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

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

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

Я лишь отреагировал на твое замечание что "Python/Ruby — How it is mostly done nowadays". В то время как, по объективным фактическим данным, только очень-очень маленькая доля всего ПО (в основном в очень узкой области написания web-сайтов) сейчас пишется на них.

UPDATE: В отличие от Руби, на вопрос о том, где именно Питон используется чаще ответить сложно.

Я бы не стал писать свой web-cтартап на Питоне не потому, что Питон плохо подходит для написания web-сайтов (совсем наоборот), а просто потому, что если бы я начинал web стартап, то мои амбиции по его функционалу, развитию, и росту были бы такие, которые бы потребовали применения других технологий с самого начала. Я бы не ждал пока меня купит Гугл и перепишет мой фронтенд, например, на Java.

Edited at 2012-05-30 05:37 pm (UTC)

Re: Я бы учил программистов так...

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

Re: Я бы учил программистов так...


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

Ну это же печаль и ужас. Всё равно, чтобы утверждалось "Для того, чтобы написать хороший текст на немецком, надо выучить латынь"

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

К сожалению, в программировании, абстракции более высокого уровня часто "протекают". Очень хорошо об этом написал Джоел Сполски в заметке "The Law Of Leaky Abstractions", поэтому аналогия с Латынью здесь не очень подходит.

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


Edited at 2012-05-29 01:21 pm (UTC)

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

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

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

хм, только мне показалось, что каждый абзац кроме предпоследнего - откровенное передергивание? с++, objective-c, c#, java ничего общего с С не имеют в плане идиом программирования... отдельные языковые конструкции похожие на С - это как 9 строчек range check "украденные" гуглом у оракла :( к сути вопроса отношения не имеют.

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

Действительно, идеомы программирования C++, Objective-C, C# и Java имеют мало общего с Си. Он некоторых из этих языков я буду писать отдельно (о C++ будет следующая заметка из этой серии). Знание языка Си не дает автоматического знания никакого из этих языков. Однако, реализация несложного алгоритма (например, алгоритма сортировки) на Си будет понятна программисту на любом из этих языков. Это существенно большая общность чем "отдельные языковые конструкции". Ядро всех этих языков основано на Си.

не соглашусь :). смотри - в алгоритме сортировки ты будешь использовать опреатор присваивания и цикл. это как раз "отдельные языковые конструкции" можно их конечно назвать ядром, но см. мой тезис про 9 строчек.
а еще на С ты там можеш начать использовать арифметику указателей (это в k&r по-моему идет сразу после описания printf) и вот ... предположим что я C в глаза не видел а знаю C# и java... что мне там будет понятно?
я могу даже сделать еще более сильное утверждение что С как языка - нет (в современном понимании языка - модель памяти, стандартные бибилиотеки). трудно назвать языком (сейчас) макропроцессор + типы данных непонятного (платформозависимого) размера + указатели + функции + пара конструкций цикла... шаг влево шаг вправо - здравствуй несколько версий посикс... где язык?? о каком однозначном мапинге в инструкции на железе идет речь (сравним мапиги gcc -02 ... -O6 ????)
я по каждому абазацу могу пройтись :) все ж неправда. "ложки нет!"
да даже по этим языковым конструкциям -- в одном "стандарте" C пременные могут быть описаны только вначале функции, в другом более "новом" можно уже описать внутри блока (но сразу досвидос "переносимость")... в общем С -- это самый динамический из динамичиских языков поскольку куча кода написана через (void *)

Edited at 2012-05-29 08:25 pm (UTC)

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

Я не зря написал что "Си в целом стандартизирован". Развернутое описание ситуации со "стандартным Си" заняло бы очень много места — там очень много проблем (даже C99 поддерживается далеко не полностью далеко не всеми). Я же не говорю о том что надо знать стандарт языка Си (это совершенно безсмысленное для обычного программиста знание).

Но это совершенно не отменяет тот факт, что Cи это лингва франка. Безусловно, хороший программист должен знать не только язык Си (я об этом уже писал и буду еще писать — stay tuned). Только тогда он сможет писать на Си такой код, который понятен всем.

Опаять же, знание С# или Java (и даже знание C++) не отменяет необходимость знать сам Си. Не зря же я написал этот пост озаглавленный "Языки которые должен знать программист: Си".

Конечно, Си может быть не только самым динамических из динамических языков. На нем можно спокойно писать и абсолютно write-only код. Да и вообще практически всё остальное сейчас в конце-концов написано на нём. Тот же Питон написан на Си. Можно вполне смотрерть на любую программу на Питоне как на программу на С (исходник CPython) которой на вход подается твой код на Питоне. Куда уж динамичней ;)


Edited at 2012-05-29 09:17 pm (UTC)

в общем и целом мне кажется что Си это не тот язык который нужно знать программисту. ну или по крайней мере точно не первый и не второй язык. иначе очень трудно будет избавиться от Сишных идиом (а именно идиомы определяют язык).
и про лингва франка тоже не поддержу. У Си очень узкая ниша. Книжек по алгоримам с массовыми примерами на Си я не знаю. Как правило везде используют псевдоязык больше похожий на алгол чем С хотя упираться в этот тезис не буду.
пассажи про динамические языки тоже опущу - они безосновательны, но об этом выше писали. в случае питона - CPython это референс имплементация. Есть PyPy, IronPyton, JPython. мой тезис о том что С в плане типизации ничуть не сильнее динамических языков заключался в дежурном Сишном паттерне кастить все в (void *) а потом использовать..
вцелом подытоживая -- мне совершенно непонятно что полезного положит программист в голову выучив Си

While I could go into a long story here about the relative merits of the two designs, suffice it to say that among the people who actually design operating systems, the debate is essentially over. Microkernels have won.
...
In the meantime, RISC chips happened, and some of them are running at over 100 MIPS. Speeds of 200 MIPS and more are likely in the coming years. These things are not going to suddenly vanish. What is going to happen is that they will gradually take over from the 80x86 line.
(C) Andy Tanenbaum, Jan 29 1992, "LINUX is obsolete"
http://groups.google.com/group/comp.os.minix/browse_thread/thread/c25870d7a41696d2/f447530d082cd95d?tvc=2

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

Тем не менее, объективный факт заключается в том, что языки с Си-подобным синтаксисом сейчас составляют абсолютное большинство языков программирования по популярности. Да и практически все языки имеют тот или иной интерфейс к Си.

Более того, я не знаю ни одного квалифицированного программиста который бы не знал язык Си. Вероятность того, что серъезный программист не столкнется с языком Си в своей каръере, чрезвычайно мала.

Нравится это кому-то или не нравится, но то, что Си это лингва франка, это факт.

Про динамические языки я напишу отдельно. Там и обсудим.

Ну как бы есть более чем серьезные причины изучать SQL и make до C.

То есть, сначала - "что хотим получить" (SQL). Потом - "что хотим получить и как это получать" (make). И только потом "что хотим получить, как получать, и в каком порядке это делать" (C). Кодирование переводом почти всегда идет с ранее изученного языка на позднее изученный. А кодирование переводом с C на PL/SQL... это ужас. Достаточно распространенный.
Есть также причина и для изучения C++ до C. Хороший код на C - это плохой, но вполне работающий код на C++. Хороший код на С++ (rara avis in terris) не только не является кодом на C, но и достаточно мало говорит о том, как написать на C какой-нибудь код, реализующий часть той же функциональности.



То, что я начал с языка Си совесем не значит, что его надо изучать первым. Скорее наоборот. Первым его точно изучать не нужно. Вопрос про обучение [детей] программированию это очень сложная тема. Я достаточно много про это знаю, но не могу назвать себя в этой области экспертом, поэтому вряд-ли буду писать об этом в стиле "надо делать так", а больше в стиле "давайте обусдим какие есть варианты".

Конечно, и про C++ и про SQL я обязательно напишу в серии "языки которые должен знать программист". C++ будет следующим.

А на make+shell+awk у тебя аллергия?

На чём ты предлагаешь писать блоки exception when unexpected_shit_on_host then?

С чего ты так решил? Я их люблю и уверен, что знать их и любить должны все программисты. Так что про make, shell, awk и т.п. я обязательно напишу. Там и подробно отпишусь за что именно их надо любить и зачем их надо знать. Тот же самый awk я даже в оригинальной заметке упомянул.


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

Ну это сейчас скорее исключение чем правило.

  • 1
?

Log in

No account? Create an account