Учил программирование в крайние годы существования СССР. Тогда самое сложное было заполучить машинное время в достаточном количестве. Т.е. проще говоря добраться до компьютера. Но вопрос я предполагаю не совсем об этом :-)
Именно при изучении лично для меня самым сложным был переход от "я могу это сделать" к "я могу это сделать профессионально и правильно". Например. Ну для чего нужно структурное программирование в общем понятно на ранних этапах обучения. Поскольку уже на этапе изучения языка многие задачи желательно разбить на подзадачи и тогда их проще решать. А вот с объектно-ориентированным это уже следующий уровень декомпозиции так сказать. Изучить ООП не то чтобы проблема. Его основы: инкапсуляция, наследование, полиморфизм в общем вполне логичны. Гораздо сложнее понять для чего это вообще нужно в реальном программировании. А не в классических примерах из учебника: есть суперкласс "живтоное" от которого наследуются два подкласса "собака" и "кошка"… Если гораздо проще устроенные процедурные программы прекрасно работают в учебных задачах. А потом научиться правильно применять. Это просто пример. Таких вещей в программировании много, которые казалось бы только усложняют решение простых учебных задач. А чтобы понять по настоящему как этим пользоваться нужно поработать уже ну хотя бы над средней сложностью проектом.