Тёмный

Авдеев Сергей (С-Петербург) собеседование python junior. Из СМИ в бэкенд разработку. 

Андрей += Пронин
Подписаться 25 тыс.
Просмотров 12 тыс.
50% 1

t.me/RU-vidPronin
Чат для общения pyhton разработчиков и им сочуствующих. Свободное общение, тестовые и вопросы с собесов и прочее. Заходите, там вам рады.
Поддержать канал: www.tinkoff.ru/rm/pronin.andr...
Обычно денежка идёт на книжки про питончик. Но иногда на светлое и тёмное.
Если Тиньков не даёт перечислить, стукните в личку телеги andpronin, придумаем что нибудь
Виш лист
Хорошие книги по Питончику, которые могу рекомендовать (и хочу купить с вашей помощью).
Изучаем Python. Двухтомник. Марк Лутц. Очень подробно и структурно (Хочу дождаться 6го издания.. )
• Изучаем Python с Марко...
Читаем и разбираем ее тут
Куплено (огромное спасибо зрителям)
Знакомство с Python | Бейдер Дэн (2023) - выглядит приятно для новичка
Чистый Python. Тонкости программирования для профи | Бейдер Дэн (2022) - хорошо для продолжения
Высоконагруженные приложения. Программирование, масштабирование, поддержка | Клеппман Мартин
Python. К вершинам мастерства | Рамальо Лучано - 2е издание - сложно для новичка, но интересно
Паттерны разработки на Python: TDD, DDD и событийно-ориентированная архитектура -- хорошо про то, когда какой фреймворк применять
Видимо, дальше появтся еще нескромные желания. Но пока - так
Моя тележка andpronin -- стучите, если что.
Мой канал про обучению python с нуля и до мидла Андрей+=Пронин
/ @pypronin
Я в других сетях
🔗Вконтакте: CaptPronin
🔗Дзен: zen.yandex.ru/id/5fbd33919412...
#python #питон #программирование #Андрей_Пронин #собеседование #

Опубликовано:

 

31 окт 2023

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 90   
@0Heal
@0Heal 7 месяцев назад
Видео подняло самооценку всем джунам
@AndyPronin
@AndyPronin 7 месяцев назад
надеюсь, еще и подкачало скилл)
@user-jh3xl2ij3r
@user-jh3xl2ij3r 5 месяцев назад
главное чтобы тебе самооценку поднял этот коммент :)
@AlexFaley
@AlexFaley 6 месяцев назад
Шикарная задачка. Не знаю как проверяет знание программирования, но поведения человека от которого хотят странного проверяет великолепно) А парень молодец, видно что упорный.
@user-kp7uw6fj1d
@user-kp7uw6fj1d 6 месяцев назад
Это НЕ СОБЕСЕДОВАНИЕ, это экзамен. Не нужно путать собеседование И ЭКЗАМЕН. Впрочем для ИТ собеседование и экзамен это одно и тоже. В других сферах деятельности такой жести нет.
@user-jh3xl2ij3r
@user-jh3xl2ij3r 5 месяцев назад
это ты росто на собеседованиях в консалтинге не был , судя по всему. В компаниях большой тройки.
@slizverg23
@slizverg23 7 месяцев назад
Ох, где-то на середине я уже потерял нить изначального задания:) Декораторы, рекурсия… Спасибо что до графов не дошли)))
@nerdizay
@nerdizay 6 месяцев назад
Можно к вам на собес?) Хочу показать мастер-класс:D + Действительно junior и ищу работу
@marat_shaydulin
@marat_shaydulin 6 месяцев назад
from functools import reduce def arg_sum(*args): if args: return reduce( lambda x, y: x + y, (arg for arg in args if type(arg) == type(args[0])) )
@Maine__Coon__1
@Maine__Coon__1 7 месяцев назад
В записи посмотрю , к сожалению работа иногда мешает просмотру ☺️
@idontknow_
@idontknow_ Месяц назад
В чем смысл задачи, я не понял. Если есть что то кроме интов, флоатов конвертировать result в строку и уже прибавлять к ней str(i). Либо отсеять инты, и не инты и на выходе проверять результат и склеивать их.
@gladatheus
@gladatheus 6 месяцев назад
Отличная задачка с декоратором, а главное в отличии от прямого решения через рекурсию можно решить обычным циклом в декораторе. И почему никто не использует reduce в таких штуках, вродеж удобно.
@aangryguyy
@aangryguyy 7 месяцев назад
Здравствуйте. Что нужно чтобы устроиться на работу Python разработчику-самоучке? У пока нет высшего образования, а Python я изучаю уже лет 5.
@AndyPronin
@AndyPronin 7 месяцев назад
Активно искать работу. И запастись терпением. Ваш кэп. Например, вот: ru-vid.comnUhamqilnwg?si=BneBlARIAj_SN9y7
@Chel1k7
@Chel1k7 7 месяцев назад
Я начал изучать пайтон в декабре прошлого года, в среднем год, устроился на работу в октябре 2023. Так же самоучка без курсов и тоже нет вышки. Так что ты явно что-то делаешь не так
@black_grizzly
@black_grizzly 7 месяцев назад
@@Chel1k7 что учили то еще помимо языка ?
@Chel1k7
@Chel1k7 7 месяцев назад
@@black_grizzly основные фреймы - django, fastapi, парсингу уделил время (реквест, селениум), телеграм ботам (aiogram), неможко покрутил-повертел next.js и react чтобы понимать как происходит взаимодействие бэка с фронтом, но в них не углублялся (в ванильный JS тоже не углублялся)
@aangryguyy
@aangryguyy 7 месяцев назад
@@Chel1k7 ну да, наверное потому что я начал искать работу только сейчас?
@roman88469
@roman88469 6 месяцев назад
А если бы в районе 24:00 испытуемый просто написал except: pass вместо рекурсии, отслеживания индексов и т.д. это было бы решением ?
@MrReape
@MrReape 6 месяцев назад
Если дать pass, то функция ничего не вернет. Что сломает не только саму функцию, но и того, кто ее вызывал. Сделал except: continue и не понял, зачем приплетали декораторы. Просто пропускаем сломанный элемент и доплюсовываем оставшиеся Можно и except: break (выходим из цикла и забываем, что после сломанного элемента было что-то еще), но по мне так это хуже вариант.
@MrReape
@MrReape 6 месяцев назад
def sum_things(*things: float | int | str | list): result = things[0] if len(things) > 0 else None for idx, thing in enumerate(things[1:]): try: result = result + thing except: print(f"index {idx+1} is broken!") continue return result print(sum_things(1,2,"12312",123))
@roman88469
@roman88469 6 месяцев назад
@@MrReape Нет, pass отработает точно так же, как и continue. Хотя continue лучше для читаемости. def sum_things(*args): if not args: return result = args[0] for x in args[1:]: try: result += x except: pass return result
@AlexFaley
@AlexFaley 6 месяцев назад
@@roman88469 А зачем там континтью. Цикл закончен, мы идем логично дальше. То есть лучше поставить pass
@evgeniy__k
@evgeniy__k 6 месяцев назад
А на этом канале кого нибудь взяли на работу? Скиньте ссылку на интервью.
@AndyPronin
@AndyPronin 6 месяцев назад
ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-8Eca6XylJJI.html из последнего - вот Гриша. Сейчас обживается активно. К себе его взял. Где то и бекендеры были. И QA
@evgeniy__k
@evgeniy__k 6 месяцев назад
Да, этот собес отличался от просмотренных.
@bunasha
@bunasha 7 месяцев назад
в чем проблема 2-ух ретернов в разных ветках условия функции?
@AndyPronin
@AndyPronin 7 месяцев назад
условие можно упростить
@user-xi9hi4tf4j
@user-xi9hi4tf4j 7 месяцев назад
можно было просто вернуть return result or None , не проверяя is None
@FunInstinct
@FunInstinct 7 месяцев назад
имелось в виду, что нужно было if not items: return None .
@ivanihnatsenkau8984
@ivanihnatsenkau8984 7 месяцев назад
Расскажите пожалуйста, как к вам можно попасть на собеседование
@AndyPronin
@AndyPronin 7 месяцев назад
Выпускникам практикума через программу трудоустройства. Подписчикам - через розыгрыш в телеграм моем
@user-np3dj8xu2d
@user-np3dj8xu2d 7 месяцев назад
блин ну может он и не знает многого но под натаскать если будет крутой чел с которым приятно будет работать и иметь дело что не маловажно. + видно что он старательный джун - огонек в глазах есть. На мой взгляд способный парень желаю ему удачи!
@AndyPronin
@AndyPronin 7 месяцев назад
Думаю, оффер не заставит долго ждать
@alchi_alchi_
@alchi_alchi_ 7 месяцев назад
Декоратор ради декоратора? Continue и всё.
@mikeofs1304
@mikeofs1304 7 месяцев назад
Хорошее задание, и правильно поставленно - и понимание и опыт разработки реальной сразу виден. А то этот несчастный литкод скоро начнут наизустить учить как Библию, а понимания это все не прибавляет
@AndyPronin
@AndyPronin 7 месяцев назад
Да. Стараюсь не брать леткод
@user-es7ho9me3w
@user-es7ho9me3w 6 месяцев назад
def sum_items(*args): data_type = str(type(args[0])) result = args[0] for item in args[1:]: if str(type(item)) == data_type: result += item return result
@roman6572
@roman6572 6 месяцев назад
Головодрочь с этими "универсальными" функциями в динамических языках. 🙂 Тайпхинты и mypy в помощь, поможет сделать нормально. Я c# девелопер 😃
@mikeofs1304
@mikeofs1304 7 месяцев назад
Досмотрел -боль страдания А можно б было def sum_iter(*args): return reduce(lambda sum, num: sum + num if type(num) in (int, float) else sum, args if args is not None else [], 0)
@AndyPronin
@AndyPronin 7 месяцев назад
А строчки сложит? ;)
@mikeofs1304
@mikeofs1304 7 месяцев назад
@@AndyPronin а этого не было в задание, в момент когда стало полагаться что входная последовательность не однородная)) но вообще понятно что в реальной надо через дженерик делать . Я просто нахожусь под дурным влиянием книжки маера ))
@PlagueisMKII
@PlagueisMKII 6 месяцев назад
Решение наркомании (если я правильно понял условие): def sum_items(*args): if not args: return _len = len(args) res = args[0] while _len: try: for item in args[1:_len]: res += item break except TypeError: res = args[0] _len -= 1 return res
@igorz5804
@igorz5804 4 месяца назад
Это выходит как exception-oriented programming. Не надо так делать. Это скорее антипаттерн. Проверьте type(last) и type(current) и если равны - то складывайте.
@artemrokhmakov6373
@artemrokhmakov6373 7 месяцев назад
я думаю что все таки, быть репортером ему наверное куда лучше,даже не знаю какой он репортер…Пусть развиваться
@user-jh3xl2ij3r
@user-jh3xl2ij3r 5 месяцев назад
давай на тебя посмотрим, может?)
@PlagueisMKII
@PlagueisMKII 6 месяцев назад
from functools import reduce def sum_items(*args): if args and hasattr(args[0], '__add__') and all(type(item) is type(args[0]) for item in args): return reduce(lambda x, y: x + y, args) return "Все аргументы должны быть одного типа и поддерживать операцию сложения" if args else None
@coinframe
@coinframe 6 месяцев назад
Видео не досмотрел еще. Работаю с php питон не знаю. Но всё происходящее мне понятно. Тут еще задача не ясна. Что мы складываем, а что удаляем или же складываем и то и другое. Проверяем аргумент является ли числом, если истина складываем и наоборот. Ну а если и то и другое одновременно нужно сложить ну это уже ерундистика полнейшая.
@7IdE
@7IdE 7 месяцев назад
Ну, для человека с ярлыком "СМИ" у него просто нулевые софты, как по мне: самопрезентация вообще на нуле, по проектам вообще ничего не рассказал, даже свою роль в проекте не выразил. Ибо после его рассказа о себе, как о разработчике и о своих проектах - у меня вообще не сформировалась никакая картинка о нем: вроде бы что-то говорил, но чем он занимался? Зачем? Почему? Ну, тут я могу и ошибаться - софты явно не мое. По хардам: 1. Когда Андрей сказал "если передадим строчку - скорее всего не сработает". Он подтвердил: "Да, не сработает." А откуда такая уверенность в том, что не сработает? Ведь строки прекрасно складываются - так почему нет? Весьма похоже на подтверждение просто "чтобы не упасть в грязь лицом". 2. Уже просто классика жанра: ставить тайп-хинты чисто ради того, чтобы показать, что ты где-то когда-то это слышал / видел, при этом не может расставить банальные хинты... 3. Проверка items == None, когда получает на входе запакованный кортеж - это прям печаль. И что еще печальнее - это дальнейшее исправлнение на "is None". Опять же, вместо того, чтобы подумать, начинает вспоминать станадартные вопросы / ответы с собесов. 4. "Питонячий код, который из декоратора обратится к переменным в функции" - вот тут сразу же вопрос про знание и понимание областей видимости. 5. Он же вообще даже не пытается уточнить, что от него требуется по задаче. Тут за 2-3 вопроса можно было бы заставить заказчика внести ясность в задачу. А он даже 1 не задал. 6. В декораторах совсем плавает: вынести логику в декоратор, задекорировать функцию и при этом оставить всю старую логику в этой же функции - это мощно. 7. Нет понимания своего же собственного кода. 8. len(items) - 1 - тут стоило бы сразу задать вопрос на тему того, чем его не устроил последний элемент. В целом, крайне неоднозначный собес: вроде бы что-то знает, что-то может, но это все такая каша - что прям страшно смотреть. Есть ряд моментов, которые бы я назвал прям критичными (выше написал), да и в целом с подкапотней не особо дружит. Хотя первая реализация через рекурсию была весьма неплохая: достаточно резво он применил рекурсию. И сделал это достаточно корректно. Пофиксить багу с range() и работало бы в соответствии с ТЗ. Хотя и ТЗ это не было уточнено. Я бы сказал: нужно структурировать все, что есть в голове, поизучать подкапотню и повторить собес. Я бы даже посмотрел на итог. P.S. Мне кажется, что фраза "если бы ты претендовал на мидла - нет, для джуна - ок" неоправдано поднимает самооценку. Слишком много каши, чтобы принимать такой код, ИМХО. P.P.S. "ПЕП8 ты сознательно не нарушаешь и получается работать в этом стиле" - он написал штуку вида args[i+1:] - без пробелов!!111!! :D
@PlagueisMKII
@PlagueisMKII 6 месяцев назад
Только зачем там рекурсия, если можно обойтись обычным циклом - не совсем понятно.
@frey4404
@frey4404 6 месяцев назад
Ну ты и токсик, просто ужас
@user-jh3xl2ij3r
@user-jh3xl2ij3r 5 месяцев назад
Как же душно... Такую ты простыню накатал просто чтобы человека размазать, и вот не лень было? "вроде бы что-то знает, что-то может, но это все такая каша - что прям страшно смотреть." - это и есть джун. Все с такого начинают.
@7IdE
@7IdE 5 месяцев назад
​@@user-jh3xl2ij3r, нет, это не джун, это стажер и меньше. И любые высказывания вида "да все там были", "да ничего - прорвешься", "да все норм - есть и хуже" - они лишь вводят в заблуждение, не давая человеку понять, что он делает что-то не так. Простыня, которую я накатал выше, предназначена лишь для того, чтобы человек сделал выводы по всему тому, что я написал: и если он эти выводы сделает, то он станет вполне себе джуном. А если бы я хотел его "размазать", то я бы даже близко не пытался не пытался пояснять и аргументировать, а просто бы написал "в утиль" - и это куда больше бы подходило под термин "размазать". Ну и самое главное: вон там выше есть коммент, в котором говорится, что, мол, такой перфоманс поднимает самооценку всем джунам - и вот таким комментом и таким кол-вом лайков под ним явно можно очень серьезно опустить самооценку человеку. Но вы оба, почему-то, решили отписаться человеку, который пытается в развернутую критику. Сказочные создания.
@user-jh3xl2ij3r
@user-jh3xl2ij3r 5 месяцев назад
@@7IdE под тем комментом нет смысла даже что то писать. Слишком жирно. У тебя хотя бы не троллинга ради было написан комментарий, поэтому и захотелось подискутировать. Ты слишком груб с человеком, который только делает первые шаги. Если мы не будем выращивать джунов, рынок будет в еще большей заднице. Новым миддлам будет неоткуда браться. Всем будет только хуже по итогу. Да и просто вспомни себя в начале, сомневаюсь что ты сразу начал писать максимально эффективный чистый код.
@dannycyberwalker
@dannycyberwalker 7 месяцев назад
Надо больше мидлов!
@user-zl5sp9yh1n
@user-zl5sp9yh1n 7 месяцев назад
Чет нулевое собеседование. Ни о чем. Красивый рассказ про проекты и всякое, но уровень.
@user-jh3xl2ij3r
@user-jh3xl2ij3r 5 месяцев назад
чет не о чем коммент.
@scatr1x
@scatr1x 7 месяцев назад
Здрасьте
@Chel1k7
@Chel1k7 7 месяцев назад
Салют
@AndyPronin
@AndyPronin 7 месяцев назад
привет
@slizverg23
@slizverg23 7 месяцев назад
Забор покрасьте! (Сорян, услышал это выражение у ребёнка в детском саду и захотелось применить)
@galandec2000
@galandec2000 7 месяцев назад
в python типы должны проверяться до того как начнется их обработка и исключение! не должно быть исключения, если тип не тот. это суть таких яп. если у вас передался не тот тип и прилетело исключение. это говнокод.. поэтому типы прописывают не везде, как к примеру TypeScript а только где они получаются и модифицируются. сама функция которая получает условно строку, должна работать хорошо в любой ситуации. если строка не прилетела а прилетела цифра, то это проблемы не функции которой она пришла а того где оно приходит. поэтому правильно проверка делается до выполнения, в месте получения данных. надеюсь понятно, ибо чет сам чуть понял что написал.😂 в типизированных яп, оно по другому. а в слабо типизированных проверки проходят в самом начале, именно где пришло, а не в середине кода или конце.
@mikeofs1304
@mikeofs1304 7 месяцев назад
Это все кстати, и много, что еще, я говорю людям считающий Пихон простым, и намного более плохое - подходящим для начала обучения программированию "нулевых" людей, особенно ООП.
@coinframe
@coinframe 6 месяцев назад
Я вообще проблем в задаче не вижу. Пусть закидают камнями, php это не язык программирования итд... Но плёвое дело для него. И полностью согласен, в чём проблема проверить аргумент на инт и отсеять строки и наоборот. Ну а если нужно одно и второе разом складывать - то это бредятина и в жизни такое не встретится в принципе.
@SMTDN
@SMTDN 5 месяцев назад
С каких пор питон стал слабо типизированным языком?
@albukerke3322
@albukerke3322 7 месяцев назад
Странное, зачем давать рандомные задачи которые имеют такую странную логику? Естественно кто шарит должен был сам уточнять что задача имеет недостаточно информации: 1)нужно ли суммировать один из типов, если да то какой? 2)или суммировать все элементы по типам, хранить их и выводить.. но выводить что? Сумму определенного типа или каждого типа данных. 3)или суммировать тот тип которого больше в списке.. 4)или суммировать первый попавшийся тип данных, а остальные просто пропускать. Это все в корне меняет способ решения. Но думаю можно было изначально логику вопроса построить получше, либо дать человеческую подсказку. Видно конечно что парень слабовато пока знает декораторы, мало практики наверное. Но задача конечно.. проверяет скорее на навык вежливого уточнения что за дичь просят разработчика сделать))
@albukerke3322
@albukerke3322 7 месяцев назад
Добавлю что очень классный скил у парня - говорить и рассуждать вслух, если бы еще вопросы задавать попутно собеседующему то будет супер.
@mikeofs1304
@mikeofs1304 7 месяцев назад
"Странное, зачем давать рандомные задачи которые имеют такую странную логику? Естественно кто шарит должен был сам уточнять что задача имеет недостаточно информации: " Это жизнь. В реальност изадача будет поставленно хреново
@7IdE
@7IdE 7 месяцев назад
Несмотря на то, что я не согласен с корректностью такой постановки, но...от собеседуемого не прозвучало вообще никаких вопросов с целью уточнения того, что от него требуется. Банально за 2-3 уточняющих вопросов и парочку примеров с вопрос "что должно выводиться в таком случае" можно будет понять, что хочет заказчик. А в итоге заказчик впаривает какую-то дичь, а разработчик даже не пытается "увидеть решение задачи глазами заказчика". Так что, в данном случае, камень в огород собеседуемого.
@nerdizay
@nerdizay 6 месяцев назад
Господи как же доооолго.. и разговоры не по теме.. пробует то, что не знает.. Зачееем!? АААрРАРРРРаа
@galandec2000
@galandec2000 7 месяцев назад
renge(len(items) - 1) - это лютый говнокод в python! это прям очень грубая ошибка. никогда так не делайте!!! это покажет то что вы вообще не знаете python а пишите на каком-то js синтаксисом python.. прикол в том что так много кто пишет.. и это реально жесть.. вы замедляете код минимум в двое! достаточно renge(items) и он нормально отработает. а так вы постоянно повторяете лишнее вычисление.😆
@user-xi9hi4tf4j
@user-xi9hi4tf4j 7 месяцев назад
ну если Items =последовательность , то не получится rAnge(items), только если items = int, поэтому если нужно обращаться через индексы к items, то только так rAnge(len(items) - 1), ну или через enumerate()
@mikeofs1304
@mikeofs1304 7 месяцев назад
"А вы точно -продюссер- паграммизд ... " Уверены прям в этом страшном " _а так вы постоянно повторяете лишнее вычисление_" ?
@7IdE
@7IdE 7 месяцев назад
Я искренне не понимаю таких людей. И "лютый говнокод", и "грубая ошибка", и "не знаете Питон" - я прям закликбейтился и подумал, что дальше будет что-то интересное. А дальше идет range(items) - которая будет падать на всех типах, кроме интов - и замедление кода в 2 раза, и повторное вычисление на каждой итерации... Ты хоть когда-нибудь пытался запускать питоновский код с range(items)? На основании чего ты взял, что вычисления происходят на каждой итерации, а не 1 раз? (это при условии, что вычисление len() вообще происходит, а не хранится изначально в атрибуте) Откуда ты взял "замедление х2 минимум"? И это я еще промолчу про то, что range пишется через "a". Почитай Лутца, что ле.
@FriskesTV
@FriskesTV 7 месяцев назад
Абобус, вычисления будет производится циклично только если ты укажешь их в условии цикла while
@justman073
@justman073 7 месяцев назад
range-объект загружает в себя последовательность на основе трёх аргументов: старт, конец, шаг (обязательно целочисленных). Делает он это только один раз и при вызове выдаёт значения последовательности по принципу генератора. Дорогой "знаток" python, прочитайте хотя бы теорию
@ivormacky5078
@ivormacky5078 7 месяцев назад
Вы определитесь безусловный переход это хорошо или плохо, читаемость кода против условной производительности, да меня учили без них кодить, но времена изменились, компиляторы поумнее нашего во многом и докапываться до этого глупо! Ну и в целом хз собеседование, вы проверяете знание синтаксиса или что, я решаю на питоне задачи больше года на литкоде, довольно неплохо я считаю, про то как передать произвольное количество переменных не знал, гуглится это меньше чем за минуту, если бы попросил у вас 1-2 минуты гугла, вы бы отказали, ахаха?)
@AlekseyMaximov
@AlekseyMaximov 4 месяца назад
услышал начальные требования, поставил на паузу, написал решение минут за 10, попивая чаёк: # ----------------------------------------------------------------------------------------------------------------------------------------- def sum_arguments(*args): result = 0 print(f"Args count: {len(args)}") for item in args: arg_type = type(item).__name__ print(f"{item=}, {arg_type=}") match arg_type: case 'int': result += item case 'str': tmp = str.strip(item) for i in tmp.split(): try: result += int(i) except ValueError as e: pass case 'list' | 'tuple': result += sum_arguments(*item) case _: pass return result ### run it data = [1, 2, 3, '4', '5', "6", [7, 8, 9], "a 100 4", 'b', (0,1), '()', " -1 ", [], "1"] res = sum_arguments(data) print(f"{res=}") # ----------------------------------------------------------------------------------------------------------------------------------------- потом начал глядеть видео дальше, и слегка был сконфужен: - нечетко поставлены общие требования задачи - не указаны инженерные требования к входящим данным, их размер, наличие, граничные значения, валидность - не определены тайминги, а так же не обсуждалась сложность решения O(?) Вобщем, что-то как то быстренько закодил. Интересно, приемлимо ли получилось?
Далее
REALLY LOVES CHIPS
00:19
Просмотров 2,5 млн
Собеседование Python developer на 4000$
25:22