Небезпеки навчання на Java

"Ви щасливчики. Ми по три місяці жили в мішках з дерюги в брудних сараях. Ми вставали о шостій ранку, прали мішки, з'їдали по кірці чорствого хліба і йшли працювати на млин, по 14 годин на день, з понеділка і до неділі, і коли ми поверталися додому, наш тато поров нас своїм ременем "

- Літаючий цирк Монті Пайтона, Чотири йоркширці

Ледача молодь.

Що може бути доброго у важкій роботі?

Вірна ознака мого старіння - моє бурчання і скарги про «сучасну молодь» і про те, як не хочуть або не можуть більше робити нічого складного.

Коли я був молодий, я вчився програмувати на перфокартах. Якщо ви випадково робили помилку, у вас не було такої «сучасної можливості», як натиснути клавішу backspace і ввести заново те, що потрібно. Вам доводилося викидати карту і починати введення заново.

Коли я починав проводити інтерв'ю з програмістами в 1991 р., я зазвичай дозволяв їм використовувати будь-яку мову програмування для вирішення мого завдання на кодування. У 99% випадків вони вибирали C.

У наші дні вони зазвичай вибирають Java.

Не зрозумійте мене неправильно: немає нічого неправильного у використанні Java як робочої мови.

Зачекайте хвилинку, я хочу трохи змінити це твердження. Я не стверджую в цій окремо взятій статті, що у використанні Java в якості робочої мови є щось неправильне. У цьому багато неправильного, але воно почекає до іншої статті.

Замість цього я хочу сказати, що Java в цілому недостатньо складна, щоб відокремити відмінних програмістів від посередніх. Можливо, це відмінна мова для роботи, але сьогодні мова не про це. Я навіть можу зайти так далеко, що скажу - факт того, що Java не складний, це фіча, а не порожній, - але це веде до даної проблеми.

Це може звучати трохи різкувато, це просто моя скромна думка, але є дві речі, яким традиційно вчать в університетах в курсі комп'ютерних наук (Computer Science, CS) і які багато людей ніколи повністю по-справжньому так і не розуміють: покажчики та рекурсія.

На самому початку навчання в коледжі ви проходите курс структур даних, з пов'язаними списками, хеш-таблицями та іншими дрібницями, з широким використанням покажчиків. Такі курси досить часто використовуються як курси для відсіву: вони так складні, що всі, хто не володіє розумовими здібностями, необхідними для CS, кидають, і це дуже добре, тому що якщо ви думаєте, що покажчики складні, то почекайте поки вам не доведеться доводити факти теорії нерухомої точки.

Всі ті юні генії, які в старших класах школи писали на Бейсиці пінг-понг для Apple II, надходять в коледжі, вибирають CompSci 101, курс по структурах даних, і коли стикаються з роботою з покажчиками, їх мізки просто вибухають, і вони вирішують перевестися на політологію, тому що тепер правова школа здається їм кращим вибором. Я багато разів бачив графіки відсіювання студентів з курсів CS, і зазвичай відсоток вибулих становить від 40% до 70%. В університетах схильні вважати це розбазарюванням; я думаю, що це просто необхідне природне відбракування людей, які просто не зможуть бути щасливі або успішні в кар'єрі програміста.

Іншим складним для багатьох студентів був курс, в якому вивчалося функціональне програмування, в тому числі рекурсивне програмування. У Массачусетському Технологічному Інституті була дуже високо поставлена планка за цими курсами, розроблений обов'язковий курс (6.001) і підручник (Абельсон і Сассман, Структури та Інтерпретація Комп'ютерних Програм (Abelson & Sussman's Structure and Interpretation of Computer Programs), які використовуються десятками шкіл або навіть для Стандарту або навіть для Кращу Cе C.

Складність цих курсів просто приголомшлива. На першій лекції ви цілком вивчаєте Scheme, і тепер ви можете бути присвячені в роботу функцій, що працюють з нерухомою точкою, які використовують інші функції на вході. Коли я зміг побороти такий курс, CSE121 в Університеті Пенсильванії, я побачив, як багато, якщо не більшість, студентів так і не змогли це зробити. Матеріал був занадто складним. Я послав електронною поштою професору довгий лист, повне ридань, що говорить про те, що Це Просто Нечесно. Хтось в університеті, мабуть, почув мене (або одного з інших скаржників), тому що тепер на цьому курсі вивчають Java.

Тепер я б вважав за краще, щоб мене не почули.

Думаєте, що ви знаєте, що це таке? Перевірте Себе Тут!

Про це і ведуться суперечки. Роки скулення ледачих студентів, подібних мені, в поєднанні зі скаргами індустрії програмного забезпечення на те, як мало американські університети випускають фахівців з CS, зробили свою справу, і за останнє десятиліття безліч бездоганних в іншому шкіл на 100% перейшли на Java. І це віталося: рекрутерам, які використовують «grep» для оцінки резюме (прим.: grep - це програма в Unix, що дозволяє вибирати рядки, в яких є потрібне слово), це, здається, подобається, і, що найкраще, в Java немає нічого достатньо складного, щоб реально відсіяти програмістів без тієї частини мозку, яка відповідає за покажчики або рекурсії, відповідно рівень відсіювання в університетах знижується, факультети CS випускають більше студентів, за це отримують більше грошей, і всім стає добре.

Щасливі учні Java-шкіл ніколи не зіткнуться з жахливими segfault (прим.: Segmentation Fault - типова помилка при зверненні за некоректною адресою) при спробах реалізувати засновані на покажчиках хеш-таблиці. Вони ніколи не робитимуть божевільних, божевільних спроб упакувати щось у біти. Вони ніколи не будуть завантажувати свої голови думками про те, як у повністю функціональних програмах значення змінної ніколи не змінюється, і все-таки воно постійно змінюється! Парадокс!

Їм не потрібна ця частина мізків, щоб отримати червоний диплом.

Невже я всього лише один з тих старомодних бурчунів, на кшталт Чотирьох Йоркширців, які хваляться тим, як важко було жити в суворі старі часи?

Ей, в 1900 р. латинь і грецький були обов'язковими предметами в коледжі, не тому, що вони були якось необхідні в житті, але тому, що їх знання було однією з обов'язкових ознак освіченої людини. У певному сенсі мої аргументи не відрізняються від тих аргументів, які наводили прихильники латині (всі чотири). "[Латинь] тренує ваш ум. тренує вашу пам'ять. Розплутування пропозицій на латині - це відмінна вправа для розуму, справжня інтелектуальна головоломка, і хороше введення в логічне мислення ", писав Скотт Баркер (Scott Barker). Але я не зміг знайти жодного університету, який досі викладає латину в обов'язковому порядку. Невже покажчики і рекурсія - це латинь і грецький комп'ютерних наук?

Отже, я легко погоджуся з тим, що програмування покажчиками сьогодні не є необхідним в 90% розробки коду, і навіть становить небезпеку в промисловому коді. Так. Чудово. І функціональне програмування не так вже й часто використовується на практиці. Згоден.

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

Без розуміння функціонального програмування ви не зможете придумати MapReduce - алгоритму, який робить Google таким добре масштабованим. Терміни Map і Reduce прийшли з Lisp і функціонального програмування. MapReduce зрозумілий будь-кому, хто пам'ятає зі свого курсу, еквівалентного 6.001, що істинно функціональні програми не мають побічних ефектів і тому легко розпаралелювані. Дуже показовий той факт, що в Google винайшли MapReduce, а в Microsoft немає, і це говорить дещо про те, чому Microsoft досі грає в наздоганялки, намагаючись змусити працювати основні функції пошукової машини, в той час як в Google перейшли до наступної проблеми: побудові Skynet найбільшого в світі паралельного суперкомп'ютера. Я не думаю, що Microsoft дійсно розуміє, наскільки вони відстали на цьому шляху.

Але навіть далеко від завдань, де важливість покажчиків і рекурсії очевидна, їх реальна значимість в тому, що створення великих систем вимагає тієї гнучкості мозку, яку ви отримуєте при їх вивченні, і тих здібностей мозку, які були вам необхідні для того, щоб не вилетіти з курсу під час навчання. Індекси та рекурсія вимагають від людини певних здібностей: міркувати, абстрактно мислити, і, що особливо важливо, бачити проблему на декількох рівнях абстракції одночасно. Тому здатність розуміти покажчики і рекурсію безпосередньо пов'язана зі здатністю бути великим програмістом.

Ніщо в освіті, побудованій повністю на Java, не відсіває студентів через недостатню гнучкість їх мізків для розуміння цих концепцій. Як роботодавець, я бачу, що 100% -Java школи почали штампувати випускників курсів CS, деякі з яких просто недостатньо розумні для того, щоб працювати програмістами з чимось більш хитромудрим, ніж Ще Один Бухгалтерський Додаток На Java, хоча вони і управилися зі скрипом з «сучасною-спрощеною-для-тупиць» курсовою роботою. Ці студенти ніколи не впоралися б з курсом 6.001 в Массачусетському Технологічному, або з CS 323 в Єлі, і, чесно кажучи, це і є причина, чому, з точки зору роботодавця, диплом Массачусетського Технологічного або Єля має більшу вагу, чим диплом Дюка, який нещодавно став Повністю-На-Java, або Penn University, який замінив Scheme і ML на Java, намагаючись викладати на ній курс, який колись майже вбив мене і моїх друзів, CSE121. Справа не в тому, що я не хочу наймати розумних хлопців з Duke або Penn - я наймаю їх - просто мені набагато складніше зрозуміти, хто вони. Раніше я міг сказати, що хлопець дійсно розумний, якщо він за кілька секунд може розібратися в рекурсивному алгоритмі, або реалізує функції, що маніпулюють зв'язковими списками на основі покажчиків, з такою швидкістю, з якою він може писати на аркуші паперу. Але у випадку випускників шкіл Java я не можу сказати, чи має претендент проблеми з цими завданнями, тому що у нього просто не вистачає відповідної освіти, або тому, що у нього немає відповідної частини мізків, необхідної для відмінної роботи в якості програміста. Пол Грехем називає їх Горе-Програмістами.

Досить погано вже те, що Школи-на-Java не відсіюють тих, хто ніколи не зможе стати великими програмістами, але на це школи цілком обґрунтовано можуть сказати, що це не їхня проблема. Індустрія, або принаймні «рекрути-використовувачі-grep», дійсно вимагають, щоб школи викладали Java.

Але «школи-тільки-на-Java» також перестали тренувати мізки студентів для того, щоб вони стали знаючими, спритними, і гнучкими достатньо, щоб могли добре проектувати програми (і я не маю на увазі об'єктно-орієнтоване «проектування», коли ви витрачаєте незчітну кількість годин, переписуючи власний код при перебудові вашої об'єктної ієрархії, або муєте такими фальшивими «проблемами» (містить «», як вибір «»,, «»,, - «, -», - «, -» Прим «, Прим». has-a vs. is-a, вибір між спадкуванням і композицією класів)). Необхідні тренування, щоб навчитися думати на декількох рівнях абстракції одночасно, що є абсолютно необхідним для проектування відмінної архітектури програмного забезпечення.

Вам може бути цікаво, чи може навчання об'єктно-орієнтованому програмуванню (ОВП) бути хорошим замінником покажчиків і рекурсії як вичищаючих курсів. Коротка відповідь - ні. Не обговорюючи гідності ОВП, можна просто сказати, що воно недостатньо складно для відсіювання посередніх програмістів. Викладання ОВП полягає в основному в запам'ятовуванні декількох словникових термінів, таких як «інкапсуляція» і «спадкування» і завчанні відповідей на безліч питань про різницю між поліморфізмом і перевантаженням операцій. Не складніше заучування знаменних дат і імен на уроках історії, ОВП ставить неадекватно просте завдання для того, щоб відлякати першокурсників. Коли у вас проблеми з ОВП, ваша програма все-таки працює, вона просто стає складною для підтримки. Нібито. Але коли у вас проблеми з покажчиками, ваша програма видає Segmentation Fault, і ви поняття не маєте, що відбувається, до тих пір поки ви не зупинитеся, не зробите глибокий вдих і не спробуєте насправді змусити свій розум працювати на двох рівнях абстракції одночасно.

Рекрутери-використовувачі-grep, до речі, висміюються тут, і для цього є вагомі доводи. Я ніколи не був знайомий з людиною, яка б розуміла Scheme, Haskell і покажчики С, і не могла б освоїти Java за пару днів, і після цього писати код на Java краще, ніж люди, що мають п'ятирічний досвід роботи з Java, але спробуйте пояснити це середньому HR-біороботу.

А що щодо місії CS-факультетів? Це не ПТУ! Їхня робота не полягає в тому, щоб підготувати людей до роботи в промисловості. Це тільки для общинних коледжів, скажуть вам, (прим.: у США дворічний коледж, що готує фахівців середньої кваліфікації для роботи на території місцевої спільноти) та державних програм перенавчання для звільнених робітників. Передбачається, що вони дають студентам фундаментальні інструменти для того, щоб ті жили своїм життям, а не готують їх до перших днів роботи. Правильно?

Все ж таки. CS це докази (рекурсія), алгоритми (рекурсія), мови (лямбда-обчислення), операційні системи (покажчики), компілятори (лямбда-обчислення) - і в результаті отримуємо, що школи-на-Java, які не вчать С і не вчать Scheme, насправді не вчать комп'ютерній науці. Наскільки марно в реальному світі розуміння концепції каррування (прим.: у функціональному програмуванні породження з однієї функції іншої функції з меншим числом аргументів; наприклад з f (x, y) = x * y отримання функції f3 (x) = f (x, 3) = 3 * x), настільки ж це необхідна передумова для вищої освіти в галузі CS. Я не розумію, чому професори в комітетах, які затверджують програми навчання в коледжах, дозволяють їх програмам тупіти до такої міри, що вони не тільки не можуть готувати програмістів, готових до роботи, вони навіть не можуть підготувати випускників, які могли б отримати ступінь PhD (прим.: аналог кандидата наук) і змагатися з ними за робочі місця. Хоча ні, зачекайте. Забудьте. Можливо я все-таки розумію.

Дійсно, якщо ви повернетеся і вивчите дискусії, які мали місце в академічних колах під час Великого Переходу На Java, ви помітите, який великий інтерес викликало питання, чи є Java досить простим для використання його в якості навчальної мови.

«Боже мій», - подумав я, - «вони намагалися відупити курс ще сильніше!» Чому б не годувати всіх студентів з ложечки? Чому б викладачам самим не робити і тести за них - тоді точно ніхто не буде переходити на гуманітарні спеціальності! Як передбачається навчити когось чогось, якщо курс навчання дбайливо сконструйований так, щоб стати ще простішим, ніж він є зараз? Здається, ставиться завдання докласти зусилля (PDF) з розробки простого підмножини Java, призначеного для вивчення студентами, випуск спрощеної документації, яка дбайливо ховає весь цей EJB/J2EE-сміття від їх ніжних мізків так, щоб вони не турбували свої крихітні головки якимись іншими класами крім тих, які необхідні для того, щоб, щоб вони не турбували свої стандартувати простий головки якимісний.

Найбільш співчутливе пояснення, чому факультети CS з таким ентузіазмом отупляють свої курси, це те, що у них буде значно більше часу для навчання актуальним концепціям CS, якщо тільки вони не будуть змушені витрачати дві лекції на те, щоб пояснити різницю між, скажімо, int і Integer в Java. Добре, якщо справа тільки в цьому, 6.001 буде для вас відмінною відповіддю: навчальна мова Scheme так проста, що вся мова може бути розказана смішним студентам приблизно за десять хвилин; після цього ви можете витратити залишок семестру на нерухомі точки.

Фух.

Я повертаюся назад до одиниць і нулям.

(У вас є одиниці? Везучий виродок! Все, що було у нас - це нулі.)

Кінець

Перекладач: Ілля Болодурін

Стаття давніша, але «зачепило».

Upd

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