Конкретная цель была: основательно разобраться в теории программирования, а так же со связанной с ней математикой.
На мой взгляд, это неконкретная цель, а основательно расплывчатая. Не совсем понятно, какой должен быть правильный путь для реализации этой цели. Вы решили, что нужно прочесть Кнута. Прочли (может быть, не полностью, но наверняка порядочно). Результатом недовольны. В чем причина? Неточная цель, а может быть - неверный путь? А главное - что отсутствуют конкретные критерии того, насколько Вы своей цели добились.
Это банально, но все-таки: по моему опыту, а также учитывая советы людей, чьему мнению доверяю, могу сказать, что эти три момента: конкретная цель, правильный путь к этой цели, а также четкие критерии того, насколько успешно движение по выбранному пути к поставленной цели - являются совершенно необходимыми условиями успеха любой деятельности. В этом смысле я сейчас достаточно скептически отношусь к любителям самообразования, которые спрашивают совета, как им самостоятельно изучить математику (программирование или что-либо другое). Не очень я в это верю. Когда человек учится в ВУЗе, то у него по крайней мере есть конкретная цель - это сдать требуемые зачеты и экзамены (естественно, речь идет о честной сдаче свои умом). Даже если эта цель и не полностью совпадает с получением реальных и полезных в будущем знаний, но все-таки сильно с этим коррелирует, а главное - какая ни есть, а все-таки понятная и конкретная цель с конкретными сроками. Есть путь, диктуемый учебным планом и планами конкретных курсов; опять-таки, какой ни есть, но по крайней мере четкий путь. Ну и с критериями все достаточно понятно.
Я вспоминаю все те случаи, когда брался за чтение какой-нибудь серьезной книги, имея желание абстрактно "получить новые знания". Насколько помню, всегда дело шло по единой схеме. Сначала, пока шел вступительный материал, процесс шел лихо: во всем подробно разбирался, все доказательства прорабатывал и т.д. Чем дальше, тем сложнее, больше непонятных вещей, медленнее. В какой-то момент начинал какие-то технически моменты пропускать, стремясь сперва хотя бы ухватить основную суть. Стоит начать пропускать, как сразу так получается, что пропускаешь все больше и больше... ведь критериев все равно нет - теряешь ты что-то от этих пропусков или нет. А также начинал замечать, что когда ссылки отсылают к предыдущим частям, которые вроде как уже прочитал, то понимаешь, что уже их подзабыл, приходится читать и вспоминать заново. И попутно начинает созревать мысль о том, что даже если книгу и дочитаешь до конца, то через месяц-другой точно так же забудешь уже все, как будто и не особо читал. А также начинаешь думать, зачем тебе все это надо, где и как это применить... а думать об этом следовало вообще-то заранее.
Наиболее же плодотворными были ситуации, в которых ты что-то изучаешь, а потом тебе придется это кому-то объяснять. Сначала - экзаменатору во время сдачи экзамена, потом - слушателям на научных семинарах, потом - студентам у доски. Тут уже не можешь позволить себе что-то пропускать, приходится усваивать все так, чтобы по крайней мере можно было рассказать логично и без очевидных пробелов.
Теоретически можно объединиться в группу единомышленников, желающих совместно изучить какой-то материал, и рассказывать его друг другу. Хотя конкретные примеры такой успешной деятельности мне неизвестны, но в принципе это возможно. Хотя может занять больше времени.
А вообще все-таки самое правильное - это идти от конкретных задач. Изучать в первую очередь то, что поможет эту задачу решить. Это может быть прикладная задача программирования, или небольшая научная проблема. В случае с программированием полезно может быть, например, брать конкретные задачи - например, с многочисленных онлайн конкурсов. Там есть огромный плюс в виде конкурентов и рейтингов, которые позволят не просто абстрактно решать, а еще и сравнивать свой уровень с другими. Будет видно, к чему можно стремиться. И тогда уже станет гораздо яснее, что из теории нужно изучать, чтобы эти конкретные задачи решать лучше.
Ну и всегда полезно по возможности иметь опытного наставника (руководителя) и группу единомышленников. Наставник может указывать путь, ставить задачи, а единомышленники позволяют организовать параллельное изучение сложных тем и проверку того, насколько ты это реально понимаешь, путем обучения друг друга.