И еще один весомый аргумент в пользу изучения Java! https://habrahabr.ru/company/otus/blog/329816/
Habr
Перспективы трудоустройства для Java-программистов
Наш образовательный проект стартовал с программы « Разработчик Java » не случайно. Во-многом появление этого курса связано с темпами роста IT-сферы и постоянного спроса на квалифицированных...
Завтра мы проведем еще один День открытых дверей по Java (последний перед началом обучения новой группы). Регистрируйтесь на http://otus.ru/dod?utm_source=telegram&utm_medium=internal&utm_campaign=dod2 и готовьте свои вопросы.
А поскольку мы по традиции разыграем бесплатное обучение - торопитесь скорее пройти вступительное тестирование, чтобы принять участие в розыгрыше!
А поскольку мы по традиции разыграем бесплатное обучение - торопитесь скорее пройти вступительное тестирование, чтобы принять участие в розыгрыше!
Через считанные минуты начинаем трансляцию второго (и последнего) Дня открытых дверей!
Присоединяйтесь, задавайте вопросы, следите за розыгрышем бесплатного обучения среди тех, кто успешно прошел вступительное тестирование!
https://www.youtube.com/chann…/UCetgtvy93o3i3CvyGXKFU3g/live
Присоединяйтесь, задавайте вопросы, следите за розыгрышем бесплатного обучения среди тех, кто успешно прошел вступительное тестирование!
https://www.youtube.com/chann…/UCetgtvy93o3i3CvyGXKFU3g/live
Кажется, ссылка была не очень... вот точно верная! https://www.youtube.com/channel/UCetgtvy93o3i3CvyGXKFU3g/live
YouTube
OTUS IT Онлайн - образование
OTUS – масштабный образовательный IT-портал. 4955473489
Наш канал предлагает более 5000+ вебинаров по программированию, разработке, аналитике, машинному обучению и менеджменту — бесплатно получайте актуальные знания, которые точно понадобятся в 2025 году.…
Наш канал предлагает более 5000+ вебинаров по программированию, разработке, аналитике, машинному обучению и менеджменту — бесплатно получайте актуальные знания, которые точно понадобятся в 2025 году.…
На втором Дне открытых дверей состоялся розыгрыш бесплатных мест в новую Java группу!
Победителями стали: Даниил Дерут и Александр с e-mail
bagyev :)
Поздравляем ребят, ждем на занятиях, желаем успехов в обучении и новых карьерных высот!
Победителями стали: Даниил Дерут и Александр с e-mail
bagyev :)
Поздравляем ребят, ждем на занятиях, желаем успехов в обучении и новых карьерных высот!
Посадка на рейс "Серьезное изучение Java group #2" завершается.
Мы провели Два дня открытых дверей (видеозапись последнего можно посмотреть тут: https://www.youtube.com/watch?v=vQFxPyLt6lc), разыграли 4 бесплатных места в новой группе, рассказывали о "фишках" Java в постах #deepjava, активно знакомили пользователей с нашим продуктом и рассказывали, почему мы больше, чем просто обучающие курсы, отвечали на вопросы и делали много-много всего, чтобы наши новые студенты получили хорошие знания и возможности профессионального и карьерного роста.
И вот новая группа сформирована и начнет занятия уже завтра! Мы желаем ребятам успехов в обучении. Энтузиазма, жажды знаний и приятного чувства от утоления этой жажды. Желаем классных проектов, драйва и позитива.
Что дальше?
Сегодня еще есть шанс присоединиться к новой группе: http://otus.ru/lessons?course=1?utm_source=telegram и начать заниматься с завтрашнего дня.
Для тех, кто делает свои первые шаги в Java и не смог сдать вступительное тестирование, мы готовим обучающие материалы, которые помогут подготовиться к набору в новую группу по Java, который будет, скорее всего, осенью (т.к. летом мы планируем запуск курсов по другим специальностям). О готовности материалов мы обязательно сообщим.
Спасибо, что вы с нами!
Мы провели Два дня открытых дверей (видеозапись последнего можно посмотреть тут: https://www.youtube.com/watch?v=vQFxPyLt6lc), разыграли 4 бесплатных места в новой группе, рассказывали о "фишках" Java в постах #deepjava, активно знакомили пользователей с нашим продуктом и рассказывали, почему мы больше, чем просто обучающие курсы, отвечали на вопросы и делали много-много всего, чтобы наши новые студенты получили хорошие знания и возможности профессионального и карьерного роста.
И вот новая группа сформирована и начнет занятия уже завтра! Мы желаем ребятам успехов в обучении. Энтузиазма, жажды знаний и приятного чувства от утоления этой жажды. Желаем классных проектов, драйва и позитива.
Что дальше?
Сегодня еще есть шанс присоединиться к новой группе: http://otus.ru/lessons?course=1?utm_source=telegram и начать заниматься с завтрашнего дня.
Для тех, кто делает свои первые шаги в Java и не смог сдать вступительное тестирование, мы готовим обучающие материалы, которые помогут подготовиться к набору в новую группу по Java, который будет, скорее всего, осенью (т.к. летом мы планируем запуск курсов по другим специальностям). О готовности материалов мы обязательно сообщим.
Спасибо, что вы с нами!
YouTube
Всё о курсе «Разработчик Java»
День Открытых Дверей — отличная возможность узнать подробнее о программе курса, особенностях онлайн-формата, навыках, компетенциях и перспективах, которые ждут выпускников после обучения. Также преподаватель расскажет о своём профессиональном опыте и ответит…
У нас отличные новости и мы спешим поделиться ими с вами!
Мы знаем, что многие ждали открытие набора на курс серьезного изучения Python - ведь этот язык имеет такое широкое применение и его популярность постоянно растет, как и спрос на хороших разработчиков на Python - поэтому по итогам обучения лучших студентов ждут на собеседования наши компании-партнеры ;)
И вот сегодня мы с радостью объявляем: набор в группу серьезного изучения Python открыт! Ждем вас: знакомьтесь с программой, сдавайте вступительное тестирование, присоединяйтесь к группе: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=post_python_new
Курс будет вести Станислав Ступников - программист рекламной системы в Mail.Ru с солидным опытом преподавания: более 5 лет - программирование на Python для студентов МГТУ им. Н.Э. Баумана; более 4 лет - курс СУБД в Технопарке Mail.Ru.
В общем, как обычно: будет не просто, но интересно; тепло, лампово и драйвово :)
И всязи с тем, что теперь в нашем канале мы будем публиковать информацию в т.ч. про Python (а не только про Java) - мы перееименовываем канал в OTUS Club Channel ✌️
Мы знаем, что многие ждали открытие набора на курс серьезного изучения Python - ведь этот язык имеет такое широкое применение и его популярность постоянно растет, как и спрос на хороших разработчиков на Python - поэтому по итогам обучения лучших студентов ждут на собеседования наши компании-партнеры ;)
И вот сегодня мы с радостью объявляем: набор в группу серьезного изучения Python открыт! Ждем вас: знакомьтесь с программой, сдавайте вступительное тестирование, присоединяйтесь к группе: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=post_python_new
Курс будет вести Станислав Ступников - программист рекламной системы в Mail.Ru с солидным опытом преподавания: более 5 лет - программирование на Python для студентов МГТУ им. Н.Э. Баумана; более 4 лет - курс СУБД в Технопарке Mail.Ru.
В общем, как обычно: будет не просто, но интересно; тепло, лампово и драйвово :)
И всязи с тем, что теперь в нашем канале мы будем публиковать информацию в т.ч. про Python (а не только про Java) - мы перееименовываем канал в OTUS Club Channel ✌️
Больше партнеров хороших и разных - больше карьерных возможностей!
Мы рады сообщить, что к числу наших партнеров присоединилась компания Tutu.ru.
+1 в копилку мотивации попасть в число лучших на курсе ;)
Мы рады сообщить, что к числу наших партнеров присоединилась компания Tutu.ru.
+1 в копилку мотивации попасть в число лучших на курсе ;)
Вам нравились наши посты с хэштегом #deepjava? Очень надеемся, что да, потому что нам очень нравится делиться полезной информацией :)
В этом месяце (до начала обучения новой группы по Python) мы хотим погружать вас в тонкости мира Python. Поэтому совсем скоро мы начнем серию постов про #deeppython!
Любителей Java обижать не будем - посты про #deepjava мы все равно будем публиковать, правда, реже.
Знание - само по себе сила!
В этом месяце (до начала обучения новой группы по Python) мы хотим погружать вас в тонкости мира Python. Поэтому совсем скоро мы начнем серию постов про #deeppython!
Любителей Java обижать не будем - посты про #deepjava мы все равно будем публиковать, правда, реже.
Знание - само по себе сила!
#deeppython
Сортировка массива - базовая операция. Каждый программист может написать несколько, а назвать - еще больше, алгоритмов сортировки. “Естественная” необходимость и любовь к красивым решениям дала нам MergeSort, QuickSort, HeapSort и т.д. Самоирония, видимо, породила такие алгоритмы как StupidSort, SleepSort и (мой любимый) TwitterSort. Что же использует Python? TimSort! Автором является широко известный в узких кругах Тим Питерс, а сам алгоритм был с портирован в Java и Android.
Это гибридный адаптивный алгоритм, который совмещает под капотом MergeSort, InsertionSort и хитрые эвристики. Алгоритм ищет в сортируемой последовательности длины N уже отсортированные подпоследовательности (run). Если такая подпоследовательность меньше определенного порогового значения (min_run) то идущие за ней дальше элементы досортировываются с помощью InsertionSort, пока критерий не будет удовлетворен. В итоге, исходная последовательность превращается в N/min_run отсортированных run’ов. run’ы сливаются последовательно и попарно, память выделяется только на элементы, которые действительно нужно перемещать. Допустим есть две подпоследовательности: A = [1, 2, 8, 9] и B = [4, 5,10, 21, 42]. В них 1, 2, 10, 21 и 42 уже находятся на своих финальных местах, что можно определить бинарным поиском B[0] в A и A[-1] в B. Память выделяется (и туда копируются) только на элементы из меньшей подпоследовательности, которые не стоят на своих финальных местах: 8 и 9. Дальше происходит слияние временной выделенного участка памяти и B с переносом элементов в A.
И, конечно, нельзя не упомянуть про режим галопа (galloping). В нем во время слияния элементы перемещаются не попарным сравнением, а сразу целой “пачкой”. Если сливаются temp = [8, 9] и B = [4, 5, 10, 21, 42] в A = [1, 2, _, _], то поиском temp[0] в B, можно определить, что элементы 4 и 5 нужно сразу перенести в A, после чего останется только дописать 8 и 9 в B. И это еще не все тонкости! Как выбирать min_run? Как искать элемент в массиве в режиме галопа? Для каких последовательностей сразу использовать InsertionSort без всей описанной “мишуры”?
Есть в чем покопаться! Приходите к нам на занятия: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=post9.06
Набор в новую группу открыт. Будет много всего интересного!
Сортировка массива - базовая операция. Каждый программист может написать несколько, а назвать - еще больше, алгоритмов сортировки. “Естественная” необходимость и любовь к красивым решениям дала нам MergeSort, QuickSort, HeapSort и т.д. Самоирония, видимо, породила такие алгоритмы как StupidSort, SleepSort и (мой любимый) TwitterSort. Что же использует Python? TimSort! Автором является широко известный в узких кругах Тим Питерс, а сам алгоритм был с портирован в Java и Android.
Это гибридный адаптивный алгоритм, который совмещает под капотом MergeSort, InsertionSort и хитрые эвристики. Алгоритм ищет в сортируемой последовательности длины N уже отсортированные подпоследовательности (run). Если такая подпоследовательность меньше определенного порогового значения (min_run) то идущие за ней дальше элементы досортировываются с помощью InsertionSort, пока критерий не будет удовлетворен. В итоге, исходная последовательность превращается в N/min_run отсортированных run’ов. run’ы сливаются последовательно и попарно, память выделяется только на элементы, которые действительно нужно перемещать. Допустим есть две подпоследовательности: A = [1, 2, 8, 9] и B = [4, 5,10, 21, 42]. В них 1, 2, 10, 21 и 42 уже находятся на своих финальных местах, что можно определить бинарным поиском B[0] в A и A[-1] в B. Память выделяется (и туда копируются) только на элементы из меньшей подпоследовательности, которые не стоят на своих финальных местах: 8 и 9. Дальше происходит слияние временной выделенного участка памяти и B с переносом элементов в A.
И, конечно, нельзя не упомянуть про режим галопа (galloping). В нем во время слияния элементы перемещаются не попарным сравнением, а сразу целой “пачкой”. Если сливаются temp = [8, 9] и B = [4, 5, 10, 21, 42] в A = [1, 2, _, _], то поиском temp[0] в B, можно определить, что элементы 4 и 5 нужно сразу перенести в A, после чего останется только дописать 8 и 9 в B. И это еще не все тонкости! Как выбирать min_run? Как искать элемент в массиве в режиме галопа? Для каких последовательностей сразу использовать InsertionSort без всей описанной “мишуры”?
Есть в чем покопаться! Приходите к нам на занятия: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=post9.06
Набор в новую группу открыт. Будет много всего интересного!
Почемы мы считаем, что у курса Python действительно интересная и актуальная программа? Почему курс рассчитан на 5 месяцев обучения и почему мы отдаем предпочтение Python 2.7?
На эти и прочие вопросы мы ответили в статье:
https://habrahabr.ru/company/otus/blog/330606/
На эти и прочие вопросы мы ответили в статье:
https://habrahabr.ru/company/otus/blog/330606/
habrahabr.ru
Набор на курс Python: почему мы думаем, что Python 2.7. — это серьезно, а Python 3 — модно
Пару дней назад мы открыли набор на один из самых долгожданных курсов — курс серьезного изучения Python. Сегодня мы хотели рассказать вам о направленности и...
#deepjava #otus
Рано или поздно Java разработчик задает себе вопрос: Hibernate или MyBatis? MyBatis или Hibernate? От ответа зависит архитектура проекта, а ответ, в свою очередь, зависит от задачи. Давайте сегодня разберемся, что они такое и когда какой лучше.
Итак, Hibernate это ORM framework. Его полное название Hibernate ORM. Он полностью поддерживает JPA и, фактически, является имплементацией JPA. Его основная задача -- понять как размечены ваши классы аннотациями ORM, построить по ним схему и собирать объекты по строкам из базы. Hibernate сам пишет за вас запросы к базе. Для вас работа с базой выглядит как работа с объектами. Сохранить объект, загрузить объект, обновить объект. Как, собственно, и должно быть. Это же Object Relational Mapping.
MyBatis это Java persistence framework. Не ORM. MyBatis связывает методы интерфейса маппера с SQL запросом. MyBatis не умеет создавать схему. И, честно говоря, вообще ничего о схеме не знает. MyBatis превращает вызов метода в запрос к базе, и как результат вызова метода возвращает результат запроса.
Что лучше подходит для вашего проекта? Смотрите сами:
Если у вас много простых объектов без сложных связей друг с другом -- Hibernate.
Если у вас сложные запросы к базе на агрегацию данных -- MyBatis.
Если вы готовы поручить фреймворку создавать и обновлять для вас схему -- Hibernate.
Если у вас работа с хранимыми процедурами -- MyBatis.
Если вы не хотите писать запросы сами, и работать с JPQL -- HIbernate.
Если вы хотите писать свой ORM (а его так или иначе придется писать) -- MyBatis.
Можно попробовать использовать оба фреймворка в одном проекте. Но мы такого на практике не встречали. Поэтому рано или поздно Java разработчик встает перед вопросом: Hibernate или MyBatis?
Рано или поздно Java разработчик задает себе вопрос: Hibernate или MyBatis? MyBatis или Hibernate? От ответа зависит архитектура проекта, а ответ, в свою очередь, зависит от задачи. Давайте сегодня разберемся, что они такое и когда какой лучше.
Итак, Hibernate это ORM framework. Его полное название Hibernate ORM. Он полностью поддерживает JPA и, фактически, является имплементацией JPA. Его основная задача -- понять как размечены ваши классы аннотациями ORM, построить по ним схему и собирать объекты по строкам из базы. Hibernate сам пишет за вас запросы к базе. Для вас работа с базой выглядит как работа с объектами. Сохранить объект, загрузить объект, обновить объект. Как, собственно, и должно быть. Это же Object Relational Mapping.
MyBatis это Java persistence framework. Не ORM. MyBatis связывает методы интерфейса маппера с SQL запросом. MyBatis не умеет создавать схему. И, честно говоря, вообще ничего о схеме не знает. MyBatis превращает вызов метода в запрос к базе, и как результат вызова метода возвращает результат запроса.
Что лучше подходит для вашего проекта? Смотрите сами:
Если у вас много простых объектов без сложных связей друг с другом -- Hibernate.
Если у вас сложные запросы к базе на агрегацию данных -- MyBatis.
Если вы готовы поручить фреймворку создавать и обновлять для вас схему -- Hibernate.
Если у вас работа с хранимыми процедурами -- MyBatis.
Если вы не хотите писать запросы сами, и работать с JPQL -- HIbernate.
Если вы хотите писать свой ORM (а его так или иначе придется писать) -- MyBatis.
Можно попробовать использовать оба фреймворка в одном проекте. Но мы такого на практике не встречали. Поэтому рано или поздно Java разработчик встает перед вопросом: Hibernate или MyBatis?
#deeppython #otus
Все мы рано или поздно сталкиваемся с необходимостью сохранить какую-то информацию, да так чтобы намертво, чтобы внуки потом еще прочитать смогли. Ежели еще нужно делать хитрые выборки по сохраненному, то обычно мы приходим к использованию реляционных СУБД. Чаще все, если посмотреть рейтинги популярности, это MySQL. Что может быть проще? Качаем последний MySQL и запускаем.
И вот уже где-то в коде устанавливается соединение с БД, выполняется простой запрос:
import MySQLdb
….
cursor.execute("UPDATE User SET likes=likes+1 WHERE Id=%s", (user_id,))
Кажется, все хорошо. Даже если тут же сделать SELECT, то можно убедиться, что у пользователя увеличилось число like’ов. Но есть нюанс, если тот же SELECT сделать из консольного клиента, то пользователь как будто и не обновлялся. А если посмотреть SHOW PROCESSLIST, то видно, что запрос в состоянии “Waiting for table metadata lock”.
А все штука в настройках по умолчанию, о которых часто забывают. В частности, в MySQL последних версий по умолчанию движок таблицы InnoDB, транзакционный, все дела. А питонячьем MySQLdb с версии 1.2.0 опция autocommit выставлена в False. Что же получается? Получается, что все ваши запросы в таком случае выполняются в рамках одной транзакции и не видны другим транзакциям до явного вызова commit (или rollback). Плюс, лочатся метаданные используемой таблицы, что отображается в processlist’е.
Что делать? Можно явно вызывать conn.commit() в конце транзакции, а можно сразу после установления соединения выставить conn.autocommit(True), тогда каждый запрос будет завершаться коммитом прозрачно для вас. Ну и конечно, нужно внимательно читать документацию и changelog’и.
Решение показалось очевидным? Тогда, возможно, вы хорошо знаете Python. Проверьте свои знания на вступительном тестировании: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=pythonpost14/06
Все мы рано или поздно сталкиваемся с необходимостью сохранить какую-то информацию, да так чтобы намертво, чтобы внуки потом еще прочитать смогли. Ежели еще нужно делать хитрые выборки по сохраненному, то обычно мы приходим к использованию реляционных СУБД. Чаще все, если посмотреть рейтинги популярности, это MySQL. Что может быть проще? Качаем последний MySQL и запускаем.
И вот уже где-то в коде устанавливается соединение с БД, выполняется простой запрос:
import MySQLdb
….
cursor.execute("UPDATE User SET likes=likes+1 WHERE Id=%s", (user_id,))
Кажется, все хорошо. Даже если тут же сделать SELECT, то можно убедиться, что у пользователя увеличилось число like’ов. Но есть нюанс, если тот же SELECT сделать из консольного клиента, то пользователь как будто и не обновлялся. А если посмотреть SHOW PROCESSLIST, то видно, что запрос в состоянии “Waiting for table metadata lock”.
А все штука в настройках по умолчанию, о которых часто забывают. В частности, в MySQL последних версий по умолчанию движок таблицы InnoDB, транзакционный, все дела. А питонячьем MySQLdb с версии 1.2.0 опция autocommit выставлена в False. Что же получается? Получается, что все ваши запросы в таком случае выполняются в рамках одной транзакции и не видны другим транзакциям до явного вызова commit (или rollback). Плюс, лочатся метаданные используемой таблицы, что отображается в processlist’е.
Что делать? Можно явно вызывать conn.commit() в конце транзакции, а можно сразу после установления соединения выставить conn.autocommit(True), тогда каждый запрос будет завершаться коммитом прозрачно для вас. Ну и конечно, нужно внимательно читать документацию и changelog’и.
Решение показалось очевидным? Тогда, возможно, вы хорошо знаете Python. Проверьте свои знания на вступительном тестировании: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=pythonpost14/06
У нас суперская новость! Нашим новым партнером стала компания Avito. Avito будут рады пригласить на собеседования наших лучших по итогам обучения студентов по курсам Python, мобильной разработки и QA (не мнее трех человек с каждого курса)
#deeppython #otus
Допустим, есть следующая иерархия классов:
class X(object): pass
class Y(object): pass
class A(X, Y): pass
class B(Y, X): pass
И в ней, вообще говоря, ничего криминального нет. Но если вы захотите отнаследоваться от A и B, то вас ждет разочарование. Выражение:
class C(A, B): pass
выдаст весьма интересную ошибку. В чем же дело?
Всему причиный алгоритм MRO (method resolution order), который используется в Python с версии 2.3. Он актуален только для new-style классов (наследуются от object), для classic классы никаких ошибок не будет в данном случае.
Под MRO некого класса C понимается его линеаризация - список предков класса, включая сам класс, отсортированный в порядке “удаленности”. Так, линеаризацией класса B из примера выше будет [B, Y, X, object]. MRO, таким образом например, определяет как, в случае множественного наследования, будет осуществляться поиск вызванного метода в данной иерархии классов.
Для конструирования линеаризации класса в Python используется C3 linearization алгоритм. Сам алгоритм разрабатывался в свое время для языка Dylan, но с тех пор был принят в Python и еще, например, в Perl 6. Линеаризацией данного класса называется слияние линеаризацией его родителей. Финальный список формируется так: сначала добавляется данный класс, потом рассматривается первый класс из линеаризации первого родителя, если он не встречаются в других списка, то добавляется в финальный и так далее, если участвует, то переходим к рассмотрению следующего родителя. Как мы видели, не все классы поддаются линеаризации данным алгоритмом.
Для classic классов MRO реализуется через поиску в глубину, слева-направо.
Кстати, эту тему мы решили осветить не просто так. Теперь у вас будет больше шансов пройти вступительное тестирование на курс Python: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=deeppython
Допустим, есть следующая иерархия классов:
class X(object): pass
class Y(object): pass
class A(X, Y): pass
class B(Y, X): pass
И в ней, вообще говоря, ничего криминального нет. Но если вы захотите отнаследоваться от A и B, то вас ждет разочарование. Выражение:
class C(A, B): pass
выдаст весьма интересную ошибку. В чем же дело?
Всему причиный алгоритм MRO (method resolution order), который используется в Python с версии 2.3. Он актуален только для new-style классов (наследуются от object), для classic классы никаких ошибок не будет в данном случае.
Под MRO некого класса C понимается его линеаризация - список предков класса, включая сам класс, отсортированный в порядке “удаленности”. Так, линеаризацией класса B из примера выше будет [B, Y, X, object]. MRO, таким образом например, определяет как, в случае множественного наследования, будет осуществляться поиск вызванного метода в данной иерархии классов.
Для конструирования линеаризации класса в Python используется C3 linearization алгоритм. Сам алгоритм разрабатывался в свое время для языка Dylan, но с тех пор был принят в Python и еще, например, в Perl 6. Линеаризацией данного класса называется слияние линеаризацией его родителей. Финальный список формируется так: сначала добавляется данный класс, потом рассматривается первый класс из линеаризации первого родителя, если он не встречаются в других списка, то добавляется в финальный и так далее, если участвует, то переходим к рассмотрению следующего родителя. Как мы видели, не все классы поддаются линеаризации данным алгоритмом.
Для classic классов MRO реализуется через поиску в глубину, слева-направо.
Кстати, эту тему мы решили осветить не просто так. Теперь у вас будет больше шансов пройти вступительное тестирование на курс Python: http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=deeppython
#deeppython #otus
Чаще всего микрооптимизации производительности только ухудшают качество кода,
его становится сложнее читать. Но их полезно знать и разбираться, потому что сам процесс исследования позволяет глубже понять язык. Вот например, что быстрее: {} или dict()? Ну или, [] или list()?
На поставленный вопрос легко ответить, воспользовавшись timeit. [] и {} в несколько раз быстрее их оппонентов. Более интересный вопрос: почему?
В данном случае ответить нам поможет модуль dis:
>>> dis.dis(compile('[]', '', 'eval'))
1 0 BUILD_LIST 0
3 RETURN_VALUE
>>> dis.dis(compile('list()', '', 'eval'))
1 0 LOAD_NAME 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
Как можно видеть, в случае [] Python сразу создает байткод инструкцию построения списка, потому что [], как и {}, являются токенами языка, которые, грубо говоря, сразу можно интерпретировать. list() и dict() же представляют из себя вызов функции, для которого нужно сначала отрезолвить их имя (поискать в globals и builtin), создать новый фрейм на стеке. Поиска в глобальной namespace’е еще можно избежать, сохранив имя в локально, т.е. Сделав, например, _list = list, но от CALL_FUNCTION избавиться не выйдет никак.
А хорошо ли ты знаешь Python? Проверь! http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=deeppython19.06
Чаще всего микрооптимизации производительности только ухудшают качество кода,
его становится сложнее читать. Но их полезно знать и разбираться, потому что сам процесс исследования позволяет глубже понять язык. Вот например, что быстрее: {} или dict()? Ну или, [] или list()?
На поставленный вопрос легко ответить, воспользовавшись timeit. [] и {} в несколько раз быстрее их оппонентов. Более интересный вопрос: почему?
В данном случае ответить нам поможет модуль dis:
>>> dis.dis(compile('[]', '', 'eval'))
1 0 BUILD_LIST 0
3 RETURN_VALUE
>>> dis.dis(compile('list()', '', 'eval'))
1 0 LOAD_NAME 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
Как можно видеть, в случае [] Python сразу создает байткод инструкцию построения списка, потому что [], как и {}, являются токенами языка, которые, грубо говоря, сразу можно интерпретировать. list() и dict() же представляют из себя вызов функции, для которого нужно сначала отрезолвить их имя (поискать в globals и builtin), создать новый фрейм на стеке. Поиска в глобальной namespace’е еще можно избежать, сохранив имя в локально, т.е. Сделав, например, _list = list, но от CALL_FUNCTION избавиться не выйдет никак.
А хорошо ли ты знаешь Python? Проверь! http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=deeppython19.06
Доброе утро! ✌ У нас хорошие новости - наших Java выпускников ждут на собеседование еще в одной компании. Нашим партнером стал Ланит.
Присоединяйтесь!
Присоединяйтесь!
Сегодня мы с удивлением обнаружили, что до старта новой группы по Python осталось всего 2 недели! (вот как заработались 😱)
А это значит, что совсем скоро наши новые студенты окунутся в многогранный мир Python и будут не только полезно, но и весело проводить время с преподавателем курса (уж мы-то знаем, что Станислав Ступников заскучать не даст).
А еще перед стартом новой группы мы проведем два дня открытых дверей, где не только ответим на все вопросы, но и (уже можно сказать по-традиции) разыграем бесплатные места в Python-группе.
Для участие в розыгрыше необходимо успешное прохождение вступительного теста. Проходите тест и регистрируйтесь на День открытых дверей:
http://otus.ru/dod?utm_source=telegram&utm_medium=internal&utm_campaign=deadlinedod
А это значит, что совсем скоро наши новые студенты окунутся в многогранный мир Python и будут не только полезно, но и весело проводить время с преподавателем курса (уж мы-то знаем, что Станислав Ступников заскучать не даст).
А еще перед стартом новой группы мы проведем два дня открытых дверей, где не только ответим на все вопросы, но и (уже можно сказать по-традиции) разыграем бесплатные места в Python-группе.
Для участие в розыгрыше необходимо успешное прохождение вступительного теста. Проходите тест и регистрируйтесь на День открытых дверей:
http://otus.ru/dod?utm_source=telegram&utm_medium=internal&utm_campaign=deadlinedod
#deeppython #otus
ООП в Python - это вам не Java. Никаких вам фабрик абстрактных классов, интерфейсов и вот этого всего. Есть, конечно, ABC и очумелые ручки, но это совсем другая история. Но классы и наследование есть, конечно. Не смотря на это, нет строгого разделения на public/private/protected. На фоне этой правды жизни возникло соглашение о том, что одно нижнее подчеркивание (_) перед именем означает пометку “только для внутреннего пользования” и даже в случае from M import * такие имена не будут импортироваться. Но это все же лишь соглашение, и если очень хочется, то ничто особо не мешает получить, например, доступ к полю, начинающемуся с нижнего подчеркивания.
Самое близкое, в некотором смысле, к private полю в Python можно получить, написав не одно, а два нижних подчеркивания перед именем. При попытке прямого доступа в таком случается получается ошибка, например:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: CachedResponse instance has no attribute ‘__intermediate_result’
Но даже такой механизм обеспечения приватности не особо сильнее предыдущего, так как на самом деле, значение поля из примера выше можно получить, обратившись к атрибуту _CachedResponse__intermediate_result. Это так называемый name mangling. Но, в основном, он все же предназначен для избежания инцидентов с одинаковыми именами полей в дочерних классах и тому подобным.
Хорошо ли ты знаешь Python? Проверь! http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=deeppython22/06
ООП в Python - это вам не Java. Никаких вам фабрик абстрактных классов, интерфейсов и вот этого всего. Есть, конечно, ABC и очумелые ручки, но это совсем другая история. Но классы и наследование есть, конечно. Не смотря на это, нет строгого разделения на public/private/protected. На фоне этой правды жизни возникло соглашение о том, что одно нижнее подчеркивание (_) перед именем означает пометку “только для внутреннего пользования” и даже в случае from M import * такие имена не будут импортироваться. Но это все же лишь соглашение, и если очень хочется, то ничто особо не мешает получить, например, доступ к полю, начинающемуся с нижнего подчеркивания.
Самое близкое, в некотором смысле, к private полю в Python можно получить, написав не одно, а два нижних подчеркивания перед именем. При попытке прямого доступа в таком случается получается ошибка, например:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: CachedResponse instance has no attribute ‘__intermediate_result’
Но даже такой механизм обеспечения приватности не особо сильнее предыдущего, так как на самом деле, значение поля из примера выше можно получить, обратившись к атрибуту _CachedResponse__intermediate_result. Это так называемый name mangling. Но, в основном, он все же предназначен для избежания инцидентов с одинаковыми именами полей в дочерних классах и тому подобным.
Хорошо ли ты знаешь Python? Проверь! http://otus.ru/lessons?course=3?utm_source=telegram&utm_medium=internal&utm_campaign=deeppython22/06
Сегодня мы расскажем о насущных задачках - как написать лотерейную машину для розыгрыша бесплатных мест на курсе. От программиста программистам :)
https://m.habrahabr.ru/company/otus/blog/331478/
https://m.habrahabr.ru/company/otus/blog/331478/
m.habrahabr.ru
Как провести розыгрыш призов среди Java программистов
Давно ли вы участвовали в лотерее или розыгрыше? Приходилось ли вам самим их устраивать? Даже если ответы: никогда и нет, уверен, что вы знаете что это такое.