Русский
Русский
English
Статистика
Реклама

Первые шаги

Сброс пароля и базовая настройка Cisco 1941

25.04.2021 10:05:42 | Автор: admin

Бывает так, что приходится сталкиваться с задачами, к решению которых ты вроде бы и не готов, а получить результат надо здесь и сейчас. Знакомо, да? Добро пожаловать в мир восточноевропейского менеджмента с соответствующей культурой управления.

Итак, допустим, ты представитель местечкового провайдера, уже знающий, как настроить какой-нибудь ASUS, но волею судьбы ещё не получивший сертификат CCNA. Рядом с тобой стоит местный админ, тоже без сертификата, глазами молящий ничего не "сбрасывать в ноль", ибо "всё работает, я просто не знаю пароль, только вы никому не говорите".

Подобные ситуации не редкость в наше ковидном мире, когда отделы со своей инфраструктурой тасуюся ежеквартально, директора направлений таинственно исчезают, а очередной управленец, дабы продемонстрировать собственную эффективность, ссорится с единственным цискарём в округе и заключает договора обслуживания при помощи сайта объявлений.

Проведём же вместе сеанс чёрной айтишной магии с последующим её разоблачением. А именно : сбросим пароль, настроим интерфейсы (локальный и внешний), соединим эти сети маршрутами и трансляцией адресов и прикроем(нет) фаерволом. Кирпич с фирменным шильдиком волшебным образом превратится в полезное сетевое устройство.

Устройство и нужные нам интерфейсы

Вот она, наша девочка. Как опытные ребята, подходим с правильной стороны:

Нас интересует её правая часть, где все порты. Голубым помечены консольные, жёлтым -- EthernetНас интересует её правая часть, где все порты. Голубым помечены консольные, жёлтым -- Ethernet

Если подключаться в Ethernet порты, которые жёлтые, то нужно знать IP адреса на этих интерфейсах и пароли на вход -- основной и "повышенный" (под которым, собственно и надо всё настраивать). Если чего-то из этого нет, то добро пожаловать в консоль. Её порты помечены нежно-голубым цветом. Такой же цвет у фирменного консольного кабеля Cisco, который обычно к этому времени потерялся.

Кабель "специальный" Cisco. Распайки есть везде.Кабель "специальный" Cisco. Распайки есть везде.

По нынешним временам COM-порт есть далеко не в каждом ноуте, поэтому придётся к этому шнурку брать стандартный COM-USB переходник. Но можно присмотреться и увидеть, что рядом со "старым" консольным портом есть mini-usb порт с тем же назначением. Переходник в данном случае встроен в циску, и, да, на него нужны драйвера. Устанавливаем их, ребутимся и подключаемся снова. После подключения Cisco через кабель miniusb в списке оборудования в разделе Порты (COM и LPT) появился Cisco Serial (COM14) (не обязательно именно 14, ну что поделать). Для дальнейшей работы рекомендую терминальную программку Putty, ибо в ней есть всё, что необходимо, и она проста, как полено. На сегодня нам от неё нужно будет подключение по интерфейсу Serial (Com14) и впоследствии Telnet (TCP23).

Сбрасываем пароли

Включаем циску и подключаемся в Putty к порту Serial (название COM14, Baud Rate 9600). Убеждаемся, что коннект есть. Далее надо перезагрузить маршрутизатор в ROMMON начальный загрузчик совсем урезанную версию операционной системы, которая загружается до cisco IOS и используется для сервисных целей (обновление IOS, восстановление пароля). Чтобы перезагрузить маршрутизатор в ROMMON, нужно прервать обычный процесс загрузки в IOS для этого в самом начале загрузки надо отправить сигнал прерывания.

Выключаем, и не разрывая консольный сеанс, Включаем Cisco 1941 и нажимаем клавишу Break (она же клавиша Pause) или комбинацию Ctrl+Break на клавиатуре (если в ноуте этого нет, в Putty по правой кнопке мыши можно вызвать special command break). Полная таблица с сигналами прерывания для разных терминалов находится здесь.

Видим приглашение в режим rommon (ROM monitor) :

rommon 1 >

Вводим команду изменения конфигурации регистра командой confreg и после перезапускаем роутер командой reset

rommon 1 > confreg 0x2142

rommon 2 > reset

Повышаем привилегии командой enable или просто en И пароль она тут не просит :)

Router1>en

Копируем запароленный конфиг в память роутера:

Router1#copy startup-config running-config

После этого применится старый конфиг, который был запаролен, но при этом мы уже находимся в привилегированном режиме, откуда можем выставить новые пароли для привилегированного режима, telnet и консоли.

Router1#conf terminal

Router1(config)#enable secret $$$NewPassword

Router1(config)#enable password $$$NewPassword

Router1(config)#line vty 0 4

Router1(config-line)#password $$$NewPassword

Router1(config-line)#login

Router1(config-line)#exit

Router1(config)#line console 0

Router1(config-line)#password $$$NewPassword

Router1(config-line)#login

Router1(config-line)#exit

Главное, в конце не забыть вернуть значения регистров по умолчанию. Если этого не сделать, то наш новый конфиг снова будет проигнорирован после перезагрузки роутера.

Router1(config)# config-register 0x2102

Router1(config)#exit

Копируем загруженный конфиг в стартовый и перезагружаемся:

Router1# copy running-config startup-config

Router1# reload

Роутер теперь с новым паролем для консоли, телнета и привилегированного режима. Ура. Можно отдать циску просиявшему админу вместе с настройками "нового интернета" (мы же от провайдера приехали, помните?). Если во взгляде местного системного администратора затаились нерешительность и страх, то поможем бедолаге.

Настройка интерфейсов

Чтоб два раза не приезжать, пробежимся по всем нужным настройкам "чтоб взлетело". У циски два "жёлтых" интерфейса: GigabitEthernet0/0 и GigabitEthernet0/1. Обычно они должны смотреть в сторону WAN и LAN соответственно, да будет так.

Адресация в WAN, допустим 100.200.100.202/30 со шлюзом провайдера 100.200.100.201

Адресация в LAN, как водится, 192.168.1.1/24 с локальным интерфейсом циски 192.168.1.1

Всё делаем из под рута:

>en

#

Для конфигурации используем команду configure terminal, для выхода - exit:

#conf t

#exit

Настраиваем локальный интерфейс:

#conf t

#interface GigabitEthernet0/1

#description LAN

#ip address 192.168.1.1 255.255.255.0

#no shutdown

#exit

Настраиваем DHCP (на всю подсеть кроме .1-.50 и .200-.254).

Исключения:

#ip dhcp excluded-address 192.168.1.200 192.168.1.254

#ip dhcp excluded-address 192.168.1.1 192.168.1.50

#ip dhcp ping packets 4

Сам пул:

#ip dhcp pool MY_DHCP_POOL_1

#import all

#network 192.168.1.0 255.255.255.0

#default-router 192.168.1.1

#dns-server 77.88.8.8

#lease 3

#exit

Всё, после этой настройки можно подключаться телнетом из локалки при желании (удобно для проверок)

При подключении должен примениться адрес из DHCP пула и пинговаться циска. Советую запустить ping -t чтоб мониторить на всякий случай.

Настраиваем внешний интерфейс:

#conf t

#interface GigabitEthernet0/0

#ip address 100.200.100.202 255.255.255.252

#no shutdown

#exit

Тут должен начать пинговаться шлюз прова - 100.200.100.201 - но только от самой циски, не с ноута (между сетями-то пакеты пока не ходят)

#ip forward-protocol nd

#ip route 0.0.0.0 0.0.0.0 100.200.100.201

Тут от самой циски должен начать пинговаться 8.8.8.8

#ip domain timeout 2

#ip name-server 8.8.8.8

#ip name-server 77.88.8.8

#ip cef

Тут от самой циски должен начать пинговаться ya.ru

#copy running-config startup-config (или просто #wr)

В итоге мы настроили на циске две сети, в которых она будет жить и трудиться. Далее надо будет их соединить.

Его величество межсетевой экран

Собственно, его величество фаер. В ипостасях NAT и списков доступа (ACL)

Тут много построено на этих самых списках, ссылки на них вбиваются как в правила интерфейсов (access-group), так и в правилах NAT, поэтому заносить надо аккуратно. Списки работают строго сверху вниз. Поэтому правила для any обычно последние (и они не нужны -- по дефолту для any всё запрещено). Список доступа может быть стандантным (access-list standard) , либо расширенным (access-list extended). Отличаются детализацией -- у стандартного только действие и источник пакетов, например.

Настройка NAT

Собираем локальную область для маскарадинга (да, я знаю, что это термин для iptables, но суть та же):

#ip access-list standard 10

#permit 192.168.1.0 0.0.0.255

#deny any

#exit

Назначаем стороны маскарадинга (интерфейсы):

#interface gigabitethernet0/1

#ip nat inside

#exit

#interface gigabitethernet0/0

#ip nat outside

#exit

Cамое важное: включаем собственно правило (одной строкой):

#ip nat inside source list 10 interface gigabitethernet0/0 overload

Закрываемся от атаки по TCPSYN:

#ip tcp synwait-time 30

Настраиваем список доступа для внешнего интерфейса (если настроить для внутреннего, то нужны разрешения для dhcp трафика). Первым делом закроем единственный сетевой доступ -- телнет (tcp 23). Если подняты http(s) или ssh тоже закрыть

Пишем список (особое внимание протоколу icmp)

#ip access-list extended 101

#deny tcp any any eq 23

#permit tcp any any

#permit udp any any

#permit icmp any any echo-reply

#permit icmp any any time-exceeded

#permit icmp any any unreachable

#deny ip any any

#exit

Вешаем список на вход во внешний интерфейс:

#int gigabitethernet0/0

#ip access-group 101 in

#exit

#copy running-config startup-config (или просто #wr)

Так то список только базовую "защиту" обеспечивает, но это головная боль админа уже. После поднятия всех сервисов и их проверки, можно написать построже и применить.

У нас пингуется всё изнутри и циска снаружи. Интернет работает, почта ходит. Все счастливы, танцуют, обнимаются, деньги в карманы засовывают. Твой социальный рейтинг растёт на глазах.

P.S. Полезные команды

Почти весь мониторинг -- это команда show. У неё есть короткая форма sh, которую я не рекомендую, ибо такая же короткая форма есть у команды shutdown

Собственно, включение чего-либо, например, интерфейса выглядит вот так:

#no shutdown

Выведем на почитать/скопировать весь конфиг:

#show running-config

Можно посмотреть возможности команды show:

#show ?

Да и любой:

#ip ?

Просмотр сводной информации по интерфейсам:

#show ip interface brief

Просмотр информации по интерфейсам L2:

#show interface summary

Просмотр адресов, выданных по DHCP:

#show ip dhcp bind

Удаление строк конфига:

#no [строка конфига]

Например, удалим шлюз по умолчанию:

#no ip default-gateway

Удаляем ВЕСЬ список доступа:

#no ip access-list extended 101

Удаление статического маршрута:

#no ip route [маршрут]

Что-ж для первого визита вполне достаточно. При помощи этой нехитрой магии ты заведёшь себе много друзей, юный падаван :) И не забудь предупредить местного админа о том, что если он как следует не настроит ACL, их сетку могут в скором времени ждать крупные неприятности. Но это уже совсем другая история.


У нас быстрые серверы для любых экспериментов.

Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!

Подробнее..

Как сменить свою специальность на программиста?

04.07.2020 18:11:54 | Автор: admin
Вам надоела ваша работа? Нет перспектив? Возможно, только начинаете свой путь?
В данной статье мы рассмотрим какой путь надо пройти, сколько времени, сил и денег надо затратить чтобы с нуля дойти до уровня, когда вам начнут присылать приглашения на работу за рубежом на очень вкусных условиях.



Здравствуйте, меня зовут Александр Зеленин. Я программист с более чем 15 годами опыта. За это время удалось поработать на позициях от веб-разработчика до CTO, в компаниях разного уровня (от 5 человек, до 2000+, стартапах, корпорациях), в разных странах и городах. Так же собеседовал более тысячи человек за всё время, вёл образовательные курсы, менторил и так далее.

* Данная статья является исключительно моим мнением. Не претендует на полность, абсолютную корректность, отсутствие ошибок, неточностей. Используйте здравый смысл при принятии любых решений и несите ответственность за них лично.

Обязательно ли релевантное высшее образование?


Нет. Оно напрямую не влияет ни на доступную работу, ни на зарплату, ни на возможности. Диплом немного помогает с процессом получения визы, но ни разу не являлся стопором. За всю мою карьеру диплом меня спрашивали только когда уже всё подписано и нужно оформить проживание в стране. Всегда работодатель находил способы решить этот вопрос.

Но, всё же, с высшим образованием проще?


Да, так как многие из тем так или иначе затрагивались при обучении. Даже если всё забылось, то восстановить знания выйдет быстрее. То если оно есть хорошо, нет ну и фиг с ним.

Я интроверт. Программист это же самый круто вариант для интровертов, да?


Ну как сказать. До определённого момента может быть и да, но уже через пару лет для роста потребуются коммуникативные навыки. Можно решать эти вопросы по мере необходимости.

Сложно учиться?


Да, очень. Конечно, это всё индивидуально, и кому-то это даётся очень легко (мне лично это всё казалось очень лёгким, но и путь был долгий), но, в основном, все кто переучивался говорят, что это очень сложно.

Основная проблема в том, что начинаешь в новом для себя поле (особенно когда был экспертом в другом) с самых низов. Постоянное ощущение что тупой, знаешь недостаточно, медленно решаешь и так далее. Это серьёзный вызов. Намного серьёзнее чем кажется на первый взгляд.

Оно того стоит вообще?


Это зависит от вашего видения мира, текущих условий и кучи других факторов специфичных для вас.

Специалист высокого уровня может рассчитывать на следующее (на момент написания этой статьи):

  • Для РФ: зарплата в районе 200 000 рублей белая, ДМС (на семью), печеньки, свободный график, оплата образования/садика детей, поездки на профильные конференции, высокую стабильность, интересные задачи, полный пакет для переезда (квартира на месяц, билеты, перевозка грузов, помощь с поиском жилья и т.п.)
  • Для Европы: зарплата в районе 5000 евро, и в принципе всё что и выше. В пакет для переезда часто ещё включают единоразовую выплату в районе 7000 евро. Часто ещё местная пенсия начинает капать и есть возможность позже получить вид на жительство / гражданство
  • США/Канада/Швейцария/Мидл Ист: зарплата в районе 10000$, и все плюшки выше

Что значит специалист высокого уровня?


Принято условно делить специалистов на 3 уровня. Часто очень разнятся требования, но в общем случае они следующие:

  1. Junior может эффективно решать задачи, но требуется помощь более опытных коллег при столкновении с неопределенностями (не понятна задача, не ясно как решать, не ясно кого спросить и так далее)
  2. Middle самостоятельная единица, которая может и задачу решить очень хорошо, и всю информацию собрать сам из нужных источников
  3. Senior эксперт, который хорошо знает не только программную часть, но и понимает бизнес, в котором работает и может предлагать решения на совершенно разных уровнях

Окей, и сколько времени учиться на каждый из уровней?


Самый первый этап, пожалуй, самый сложный психологически. На Juniorа вам потребуется около 1500 часов чистого времени (это полгода по 8 часов каждый день).

После чего джуниором проработаете около 1.5 лет.

После чего мидлом ешё года два.

Если не меняли предметную область, то добро пожаловать в сеньёры (4-5 лет суммарно).

Погоди, погоди Я вот видел курсы, там 3 раза в неделю по 2 часа и через два месяца мне обещают зарплату в 100 000 в месяц!


Ну если обещают, значит так и будет (нет).

Я вёл несколько подобных курсов исключительно из личного интереса. Даже увеличив нагрузку на учащихся по часам в 2.5 раза (по 5 часов), к концу второго месяца получался хороший обзор технологий.

Конкурентоспособность после таких курсов примерно никакая. В зачёт опыта такое не идёт. Ну т.е. вы можете в резюме написать хоть 5 лет опыта, но опыта это не даст.

Окей, окей, а вообще польза от курсов платных есть?


Вообще есть, если не сидеть и не ждать у моря погоды, а активно использовать возможность общения с ментором и при условии, что помимо этих курсов (которые вроде 6 часов в неделю) вы ещё вкладываете свои 34 часа сверху.

Какие курсы порекомендуешь?


Бесплатные. Я серьёзно. Главная ценность курсов общение с ментором. На этом их польза заканчивается. Проблема многих подобных платформ в том, что: на них много участников и внимание ментора рассеивается, менторы не квалифицированы.

Часто платформы предлагают какие-то сущие копейки за их проведение, что практически сразу исключает появление хороших специалистов готовых их вести (кроме идейных, которых мало и фиг найдёшь).

Эээ, так как тогда учиться?


  1. 1. Обязательно нужно найти личного ментора.
    Без этого весь процесс будет либо замедлен в разы, либо уйдёте, не туда потеряв кучу времени. Как найти ментора? Лучший способ это среди друзей и знакомых, кто либо уже программист, либо учится (хотя бы полгода). Обычно программисты не против делиться знаниями и помогать.
    Другой способ это нанять ментора. Минус этого способа в том, что он стоит денег. Плюс в том, что можно более точно подобрать под свои нужды. Тут надо учитывать зарплату хороших спецов (см в предыдущих вопросах) и понимать, что даже несколько часов в неделю обойдутся прилично.
  2. 2. Определиться, где вы хотите работать и что делать
    Это нужно сразу, чтобы подобрать релевантные технологии для изучения и быть полезным этой компании через полгода
  3. 3. Составить план и поставить сроки
    Составить план поможет ментор. Самому это нереально, потому что ты не знаешь то, что ты не знаешь

Ментор, ментор что, совсем никак без него?


Можно и без него. Но тогда надо намного больше читать, делать, пытаться ориентироваться во всём и перепроверять себя постоянно.

Мне доводилось общаться с людьми, у которых 10+ лет опыта, а по знаниям они даже до джунов не дотягивают. Как так выходит вопрос сложный. Отловить момент стагнации непросто.
Можно мониторить рынок, смотреть какие технологии ищут, смотреть разные решения свежие и так далее.

А потом найти ментора. Даже если ты уже сеньёр, всегда круто получить консультацию от более опытного специалиста.

Статья, вроде, про то как сменить специальность, а ты говоришь что нужно пол года по 8 часов. Как совмещать с работой то? Может год по 4 часа?


Подловили. Это очень сложный вопрос. По предыдущему опыту сокращение количества часов увеличивает срок обучения непропорционально (т.е. по 4 часа будет не ожидаемый год, а, скажем, 1.5-2). Так же, в зависимости от текущей работы, усвоение сложного материала может просто не идти и всё, то есть совмещать может не получится. Это всё зависит, всё индивидуально.
Один из способов это накопить средств и уделить полгода на такой переход. Это может быть очень сложным, когда уже есть семья или другие требования в виде ипотек и подобного. А ещё может получиться что с ходу сложно найти работу или какие-либо непредвиденные обстоятельства типа короновируса.

Другой способ это ну фигачить по полной. А вы чего хотели? :-D

У меня друг закончил курсы за два месяца и начал получать 5000$ в месяц сразу после


Несколько вариантов: либо он врёт, либо он гений (в этом случае курс тут не причём, совпало), либо ему повезло (знакомый нанял по-хитрому и т.п.), либо это что-то прям супер узкоспециализированное и он нашел лазейку. Пусть расскажет как. Ещё бывает, когда стартап не знает куда деньги от инвестора тратить и переплачивает явно. В первой же компании с адекватной разработкой картина будет совсем иная.

Где искать работу?


В столицах или, минимум, городах-миллионниках. Если вы не в Москве, Киеве, Минске или где вы там готовьтесь к переезду. Локальные рынки слишком малы и не могут предоставить достаточно вакансий (особенно для начинающих специалистов), возможности для роста малы и так далее. Вообще если удалить всю статью, и оставить только эту рекомендацию это будет одним из лучших решений для карьеры (!, но может быть не лучшим для других ваших факторов).

Есть исключения, когда офисы разработки некоторых крупных компаний находятся в небольших городах. Если вы целите в такую компанию, или она есть в вашем городе желательно заранее сравнить все варианты друг с другом.

Можно ли устроиться сразу на удалёнку?


Можно, это будет сложнее, в первую очередь, для вас. Не потому, что сама работа отличается, а потому что ответы на вопросы будут с задержкой, не будет возможности что бы подошел человек и пальцем показал, где что и почему. Да, есть куча инструментов сейчас (тивью, чаты, скайпы, доски разные), но в плане комфорта и скорости коммуникации оно отличается. Если целить на удалёнку, то надо быть готовым фигачить х2 от нормы, что бы хотя бы поспевать за адекватным темпом.

Мне 45. Возьмут ли меня Juniurом без живого опыта?


Да, возьмут. Возраст вам даже в плюс сыграет, потому что много опыта из жизни хорошо перекладывается на технологии. С большой вероятностью пройти путь до сеньёра у вас выйдет намного быстрее, именно благодаря житейскому опыту (который начинает играть большую роль со стадии мидла, чем технические навыки). С релокациями в некоторые страны может быть сложнее если и возраст большой, и вышки нет, но это тоже всё решаемо.

Какой язык учить?


Зависит от того, чем вы хотите заниматься. Если не хотите играть в лотерейку и пойти по надёжному пути Java ваш выбор. Во всяком случае он позволит пройти весь путь без сильной технологической смены и с очень хорошей оплатой.

Если у вас есть друг, который обещает устроить вас PHP разработчиком уже через полгода это может быть также хорошим кандидатом. Потому что язык не важен.

Я думал ты пошутишь про английский. Надо его учить?


Не на старте. Несмотря на то, что куча документации, информации и статей идут на английском, это всё можно поглощать через переводчики. Английский понадобится, когда решите переезжать. Хорошим моментом для начала изучения может быть через пару месяцев после устройства на работу Juniorом. И да, обязательно нужно будет общение с носителями языка будьте готовы в это также вложить денег.

Про переводчик мини-пример: буквально недавно пришлось столкнуться с библиотекой, актуальная документация для которой существует только на китайском (MyBatis-Plus) гугл транслейт помог мне разобраться что к чему без особых приключений.

Погоди, ты сказал язык не важен что?


Это не совсем так. Он важен, конечно, но после определённого этапа (senior) вам будет всё равно на каком языке писать. Концепты, на которых строится программа, переносятся из языка в язык и именно их изучение занимает намного большее время.

Условно говоря, это можно представить, что профессиональный писатель решил написать рассказ на не родном языке рассказ получится не такой выразительный и красивый, но сама история будет крутой, потому что он уже знает, как писать крутую историю. Язык это лишь инструмент донесения.

Окей, можешь накидать мне план что делать то?


  1. Определитесь реально оно вам нужно. Стоит ли оно того?
  2. Решите чем хотите заниматься. В идеале составить список компаний, в которых хотели бы работать. В идеале выбрать, где хотите быть через полгода, через два и через пять.
  3. Напишите в компании, где хотите через полгода работать. Узнайте условия найма, что нужно выучить и так далее.
  4. Составьте план тем, которые надо изучить (из описания вакансий и информации из пунктов 2 и 3)
  5. Учите, практикуйте. Каждый день. Каждый. Обязательно. Без пауз.
  6. Решайте задачки на платформах типа Leetcode и Hackerrank. Минимум 1 в день, хотя бы easy уровень.
  7. По мере продвижения можно контактировать с рекрутерами из компаний и искать возможность чтобы вас наняли. Чем раньше, тем лучше. Для увеличения шансов можно попробовать сделать какое-нибудь мини-решение полезное для компании, чтобы заинтересовать их.
  8. Найдите ментора.

Вне зависимости от языка список тем, которые я рекомендую включить в план: контроль версий (git, github), структуры и алгоритмы (знать все распространённые, big O, знать что что-то такое есть и уметь найти быстро), IDE (зачем, как настроить), отладка и профилирование (как искать ошибки, точки остановки и прочее), тестирование (написание хотя бы простейших тестов и понимание что включать в них), базы данных (реляционные, сетевые, документо-ориентированные), документирование (как писать, зачем), планирование и приоритизация (сколько займёт, что делать и когда), изучить Style Gudie по вашему языку, linux (базовое понимание что там, зачем и куда, умение запустить свой код там), пакетные менеджеры (как пользоваться, зачем, как поддерживать), семантичное версирование (зачем оно, как следовать), фреймворки (на нужном языке, хотя бы для ознакомления несколько), инструменты для сборки и автоматизации, криптография (базово что существует, а не как сделать), авторизация и аутентификация (что есть что и что для этого существует).

Насколько глубоко копать в каждую тему зависит от условий, что решили изучать и так далее. На какие-то темы хватит и 15 минут, на какие-то можно и месяц-два выделить из полугода.

Я видел, что компания, которая мне интересна обучает с нуля и нанимает. В чём подвох?


В низкой зарплате первые год-два. Но вообще это довольно крутой вариант, так как при должной мотивации это гарантированная работа, живой опыт и заинтересованные менторы, которые будут вас учить именно тому, что требуется компании. Теоретически это может снизить вариации после или удлинить срок роста, но это очень зависит от конкретных компаний и предложений. Если компания из списка вашего интереса имеет подобные стажировки с нуля стоит к ним присмотреться.

Жесть, всё сложно.


И да и нет. Сложнее всего на старте. Дальше многие концепции запоминаются и их не надо держать в голове. Очень многие вещи гуглятся за 10 секунд, но при условии, что вы знаете, что гуглить.
Подробнее..

Не практичный pythonпишем декоратор в однустроку

14.06.2021 16:14:45 | Автор: admin

Давеча, с коллегой, на работе поспорили что нельзя написать кэширующий декоратор в 4 строки, я утверждал что можно. Все началось с 4-х строк, закончилось функциональным программированием кучей lambda выражений в одну строку и декоратором в одну строку.

Дисклеймер

Такой код не попадает в мои проекты или проекты моей команды, и все что описано ниже было написано в рамках академического изыскания. Я понимает что важное преимущество языка программирования python в его читабельности. Автором, из изменяющих сознания вещества, при написании данного поста, было использовано только кофе.

Пролог

Идея написать декоратор в 4 строки меня изначально никак не трогала. Было просто интересно написать декоратор. Но в процессе спортивный интерес взял верх. Изначально все начиналось с простого кэширующего декоратора.

data = {}  # словарь для сохарения кэшируемых данныхdef decor_cache(func):      def wrapper(*args):        # создаем ключ из назвнии функции которую          # кэшируем и аргументов которые передаем        key = f"{func.__name__}{args}"         # проверяем кэшировли дунную функцию с аргументами         if args in data:            return data.get(key)        else:            # если кэшируем впервые            response = func(args) # запускаем функцию с аргументами             data[key] = response # кэшируем результат             return response      return wrapper

Сейчас задача из 18 строк кода, 11 если удалить пробелы и комментарии, сделать 4 строки. Первое что приходит на ум, записать конструкцию ifelse в одну строчку.

data = {}  # словарь для сохарения кэшируемых данныхdef decor_cache(func):      def wrapper(*args):        # создаем ключ из назвнии функции которую          # кэшируем и аргументов которые передаем        key = f"{func.__name__}{args}"        if not args in data            # если кэшируем впервые            response = func(args) # запускаем функцию с аргументами             data[key] = response # кэшируем результат         return data.get(key) if args in data else response         return wrapper

Теперь у нас 15 строк кода против 18, и появился ещё один if, что создает дополнительную вычислительную нагрузку, но сегодня мы собрались не для улучшению performance. Давайте добавим в этот мир энтропии и немного copy-paste и упростим переменную key.

data = {}  # словарь для сохарения кэшируемых данныхdef decor_cache(func):      def wrapper(*args):        if not args in data            # если кэшируем впервые            response = func(args) # запускаем функцию с аргументами             data[f"{func.__name__}{args}"] = response # кэшируем результат         return data.get(f"{func.__name__}{args}") if args in data else response         return wrapper

Теперь мы имеем 12 строк, без пробелов и комментариев 8 строк. Нам пока этого не достаточно, цель 4 строчки, и надо упростить ещё. Мы помним что декораторэто функция которая должна возвращать callable объект (функцию). Функцией может быть и lambda! Значит мы можем упростить и функцию wrapper и заменить её на lambdaанонимную функцию. И возвращать из функции "декоратора", анонимную функцию.

data = {}  # словарь для сохарения кэшируемых данныхdef decor_cache(func):  cache = labda *args: data.get(f"{func.__name__}{args}") if args in data else data[f"{func.__name__}{args}"] = func(args)     return labda *args: cache(*args) if cache(*args) else data.get(f"{func.__name__}{args}")

Цель достигнута! Декоратор в 4 строки, чистого кодаполучился. Как можно увидеть одной lambda функцией не обошлось, пришлось создать две lambda функцию. Первая lambda делает две вещи: если объект уже был закешировав возвращаем ранее закешировнанное значение и кэширует объект если он не был ранее кэширован но в таком случае мы нечего не возвращаем.

Первая lambda функция теперь у нас не анонимная её пришлось записать в переменную чтобы к ней можно было обращаться по имени переменной. Вторая lambda делает примерно тоже самое что и первая только обращалась к первой lambda по имени, кеширует и получает значения из кеша, в случае если первая lambda не вернула значение, значит объект новый и он был закэширован и значит вторая lambda вернет входящие значение.

Конструкция получилась громоздкой, но все равно читаемая, более или менеепри условии если вы легко читаете lambda выражения. Много условностей, но это ещё не ад но мы к нему приближаемся. После всего проделанного пути все ещё кажется что можно ещё сократить количество строк кода. Мы уже вошли во вкус. Например те-же две lambda выражения можно совместить в одно выражение. Давайте объеденим две lambda функции в одну.

Для этого нам надо пойти на некоторое ухищрение, использовать тернарный оператор or. Тернарный оператор принимает два значения, справа и слева относительно себя, и пытается получить логический ответ True или False. Как оператор сравнения. Для того чтобы вычислить конструкцию слева и справа интерпретатор python выполнит код справа и слева. Слева у нас конструкция memory.update({f"{func.name}_{args[0]}": func(args[0])}) данное выражение вернет нам None метод update всегда будет возвращать нам None тернарный оператор воспримит этого как False и не будет это выводить, но главное что он выполнит этот код и мы обновим переменную memory. Справа у нас конструкция получения элемента по индексу из tupla, выражение простое и всегда будет давать результат, если в tuple будет запрашиваемый индекс.

data = {}  # словарь для сохарения кэшируемых данныхdef decor_cache(func):    return lambda *args: memory.get(f"{func.__name__}_{args[0]}") if f"{func.__name__}_{args[0]}" in memory else (lambda: memory.update({f"{func.__name__}_{args[0]}": func(args[0])}) or args[0])()

Отлично мы почти получили что хотели, меньше строчек кода две lambda функции в одной строке. Появляется вопрос, зачем нам здесь тогда функция decorator_cache, давайте её тоже сделаем lambda выражением но сохраним в переменную, чтобы ей можно было пользоваться по имени.

data = {}  # словарь для сохарения кэшируемых данныхdecor_cache = lambda func: lambda *args: memory.get(f"{func.__name__}_{args[0]}") if f"{func.__name__}_{args[0]}" in memory else (lambda: memory.update({f"{func.__name__}_{args[0]}": func(args[0])}) or args[0])()

Нарушая все паттерны, нам удалось создать кэширующий декоратор, почти в одну строку. Почти, потому что формально у нас есть строка объявления переменной data. Это мне не давало покоя... примерно 10 минут, пока не вспомнил что в python есть функция globals().

Функцияglobals()возвращает словарь с глобальной таблицей символов, определённых в модуле. По сути выдает словарь глобальных переменных (ключимя переменной, значениессылка на объект). Так мы получаем возможность создавать переменные в одно выражение, одной строкой. Давайте тогда для создания переменной с пустым словарем, будем использовать следующую конструкцию:

globals().update({memory: {}})

И для получения значения переменной конструкцию с get:

globals().get(memory)

После чего мы применили это на наш декоратор, и теперь действительно все получилось уместить в одну строку.

decor_cache = lambda func: lambda *args: globals().get("memory").get(f"{func.__name__}_{args[0]}") if f"{func.__name__}_{args[0]}" in globals().get("memory") else (lambda : globals().get("memory").update({f"{func.__name__}_{args[0]}": func(args[0])}) or args[0])()

Отлично, казалось мы сделали не невозможное говнокод описали декоратор в одну строку. Немного сложно, и плохо читаймо, но конкретный пример нарачито спецально был доведен до предела, для демонстрации что lambda выражение это не сложный инструмент, и в качестве доказательства продемонстривать что любой код можно записать в одну строку.

Итоги

Все выше описанное служит академическим целям. Показать что функциональный подход бывает удобным и веселым, в сравнении со скучным декларативным ООП подход. Не надо бояться или недооценивать функциональное программирование. Это отличный инструмент, который можно использовать чаще, при повседневных задачах.

Надеюсь данный пост, поможет вам или вашим коллегам полюбить функциональный подход и лучше понять как работают lambda выражения.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru