DataSkewer – Telegram
DataSkewer
212 subscribers
52 photos
1 video
3 files
10 links
Канал с рассуждениями и заметками о работа DE.
Download Telegram
😡😡😡 Антитоп Антипаттернов при написании кода в Питоне
Кое что вобрал от своих коллег, к чему то пришел сам:
итак

1) Переменные названы непонятно для стороннего человека или не до конца объясняют суть переменной

hrs = 5
weeks = 3
for p in products:
print(p)


2) Неиспользуемые переменные остаются в коде

for i, product in enumerate(products): 
print(i)


3) «Магические» числа в коде

for I in range(24):


4) Переменные названы неконсистентно

kids_card =''
det_union_month=''


5) Функция слишком длинная и принимает 5 и более аргументов

6) Функция выполняет несколько дел:

def create_and_push():


7) Используется булевый флаг для изменения поведения функции

def round_number(value: float, up: bool) -> float:


8) Такие артефакты в коде

def hello_name(name):
print(name)


9) Не используем названия аргументов при вызове функции

tournament_search("Chess", False, 2023, True)


10) Проверяем на правильность, а не "пробуем" выполнить код с полученными данными

if not os.path.isfile(filename):
print('File does not exist.')
if not os.access(filename, os.W_OK):
print('You dont have write permission.')
with open(filename, 'w') as file:
file.write('Hello, World!')
return(f"Hello {name}")


11) Не используем менеджер контекстов

file = open(file_path, 'w')
file.write('Hello, World!')
file.close()


12) Комментируем слишком подробно или не комментируем совсем
👍9🤬2🔥1
😎😎😎 А теперь поговорим как раз таки о лучших практиках при написании кода на Питоне:

1) Переменные названы понятно любому, кто взглянет на код. Даже длинные названия приемлемы в угоду понятности.

hours_elapsed = 5
weeks_when_data_is_valid = 3
for product in products:


2) Неиспользуемые переменные заменяются на _

for i, _ in enumerate(products):
print(i)



3) Переменные названы по определенному принципу

kids_card
kids_union_month


4) Нет «магических» чисел, но есть переменные с нормальным названием

hours_in_day = 24
for I in range(hours_in_day):


5) Функция нормального размера - 40 строчек кода в одной функции MAX

6) Функция выполняет только одно дело:

def create():
...
def push():
...


7) Создаем две функции вместо булевого флага (вспоминаем функцию round_number из прошлого поста)

def round_up(value: float) -> float:
...
def round_down(value: float) -> float:
...


8) Создаем и используем класс, вместо кучи аргументов функции

class BlogPost:
def __init__(self, noscript, author, created_timestamp,
updated_timestamp, content):

blog_post1 = BlogPost(…)
def render_blog_post(blog_post):
….
render_blog_post(blog_post1)


9) Используем аннотации типов при определении функции

def hello_name(name: str) -> str: 
return(f"Hello {name}")


10) Используем названия аргументов при вызове функции

tournament_search(game="Chess", include_private=False, year=2023, popular=True)


11) Пробуем и выдаем ошибку вместо попытки включить все возможные проверки на правильность

try:
with open(filename, 'w') as file:
file.write('Hello, World!')

except FileNotFoundError:
print('File does not exist.')
except PermissionError:
print('You dont have write permission.')
except OSError as exc:
print(f'An OSError has occurred:\n{exc}')

12) Используем менеджер контекстов

with open(file_path, 'w') as file:
file.write('Hello, World!')
🔥13👍2👏1
🗑️ Эти вопросы всегда задают при собесах на должности связанные с Python. 🗑️

Как работает garbage collector и зачем он нужен? Какие механизмы очистки мусора существуют?

Python разработчики не заботятся о таких вещах, как освобождение и выделение памяти, что свойственно для разработки на C++ и C - эту проблему решает garbage collector.
Как только созданные объекты больше не нужны, сборщик мусора автоматически освободит память из-под них.
CPython (стандартный интерпретатор Python) использует два механизма для сборки мусора - подсчет ссылок на объекты и generational garbage collector (модуль gc в стандартной библиотеке Python).

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

В Python с помощью функции sys.getrefcount() можно узнать количество ссылок на объект.

import sys

test_list = [1,2,3]
print(sys.getrefcount(test_list))
test_list_2 = test_list
print(sys.getrefcount(test_list_2))


Результат
2
3

В примере создается список и на него ссылается переменная test_list, количество ссылок равно 1. Когда применяется функция sys.getrefcount(), количество ссылок возрастает до 2. Затем мы создаем еще одну переменную test_list_2 и присваиваем ей переменную test_list, счетчик ссылок равен 2, а при повторном применении getrefcount() становится равным 3.
Функция sys.getrefcount() обычно возвращает количество ссылок, большее на единицу, чем ожидалось.
Это связано с созданием временной ссылки на аргумент, который передается в функцию.

Но вот в чем нюанс, - алгоритм подсчета ссылок, не может разрешить циклические зависимости. Эту проблему призван решить generational garbage collector (GGC).

Циклическая ссылка - это когда один или несколько объектов ссылаются друг на друга.

a = []
a.append(a)


Здесь список ссылается сам на себя.

Если вызвать метод del(), то произойдет удаление ссылок на объекты. Если бы не было GGC, то объекты так бы и остались висеть в памяти, хотя и были бы недоступны для разработчика. (Нечто подобное происходит в спарке если неправильно почистить кэш см. посты выше)

В отличие от подсчета ссылок, GGC не срабатывает в реальном времени и запускается периодически. Для определения частоты запусков есть особая встроенная логика.
Generational означает «относящийся к определенному поколению» (generation - поколение), в GGC все объекты разделяет на три поколения. Изначально все объекты помещаются в первое поколение, живут там некоторое время, и большинство из них очищается, остальная часть перемещается во второе поколение и потом в третье. Чем выше поколение, тем реже оно сканируется на мусор.
Для выявления циклических ссылок GGC итерирует каждый объект в поколении и временно удаляет все ссылки, на которые этот объект ссылается. После полного обхода все объекты, у которых счетчик ссылок меньше двух, считаются недоступными и удаляются.
GGC как модуль несет для разработчика возможность управлять сборщиком мусора для циклических ссылок при необходимости. его можно вызвать написав import gc.
👍73🔥1
🚑 Поговорим о таком явлении как mangling в Python. (от англ. mangle - ломать, серьезно повреждать, калечить) в русском коммьюнити это известно как "искажение" (звучит не так запоминающееся по мне)
Эта особенность языка позволяющая обращаться к приватным методам и атрибутам, в обход условных ограничений.

Но все по порядку:

В Python можно выделить три уровня доступа данным:

public - доступно всем;
private - доступно только внутри класса;
protected - доступно внутри класса и внутри классов-наследников.
Уровень public - это уровень по умолчанию, не нужно использовать особые конструкции, чтобы сделать атрибут или метод публичным.

Чтобы сделать атрибут или метод protected, нужно добавить один символ _ перед названием

Чтобы сделать атрибут или метод private, нужно добавить два символа __ перед названием:

и казалось бы на этом все, в языке работает стандартная инкапсуляция, и к этим данным не обратиться.
Но нет, хоть при прямом доступе и произойдет ошибка, в Python регулирование инкапсуляции - это лишь условность и договоренность между разработчиками. Когда один разработчик видит _ и __ в атрибуте или методе, то будучи порядочным человеком - он понимает, что другой разработчик так назвал их желая "скрыть" их от прямого использования, а значит за этим была какая то логика и смысл, которые не стоит нарушать.

теперь возвращаемся к явлению mangling - "калеча" исходное название класса можно обращаться к приватным атрибутам и методам как в примере ниже:

class BankCard:
__serial_number = "1111 2222 3333 4444" # private-переменная
__pin = 955 # private-переменная

def __get_pin(self): # private-метод
print( "My pin is : ", self.__pin)
bank_card = BankCard()
bank_card._BankCard__get_pin()
bank_card._BankCard__serial_number = "2222 3333 4444 66666"
print( "New serial number is ", bank_card._BankCard__serial_number )

однако если бы обратились напрямую:

bank_card.__get_pin()
bank_card.__serial_number

то получили бы ошибку

Traceback (most recent call last):
File "main.py", line 8, in <module>
bank_card.__get_pin()
AttributeError: 'BankCard' object has no attribute '__get_pin'

еще интересно посмотреть на список всех атрибутов нового объекта,

print(dir(bank_card))

получим:

['_BankCard__get_pin', '_BankCard__pin', '_BankCard__serial_number', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']


вот они с лева на право:
_BankCard__get_pin
_BankCard__pin
_BankCard__serial_number

Это относится к вредным советам и особенностям языка, лично мне никогда не приходилось с этим сталкиваться и использовать в работе - но я считаю, что знать такое полезно.

теоретически это можно использовать при наследовании, тк при стандартном сценарии - производный класс затрет родительский метод - однако с помощью mangling это можно обойти сделав оба метода приватными.

class baseClass:
def __myFunc(self):
print("I'm a parent.")

class derivedClass(baseClass):
def __myFunc(self):
print("I'm a child.")

obj=derivedClass()

obj._derivedClass__myFunc()
obj._baseClass__myFunc()
🔥84😢1🆒1
🕹Хочу рассказать об очень интересной браузерной игре в которой можно хорошо научиться пользоваться линуксом.

Игра называется "Terminus", разработана в одном из самых уважаемых университетов мира в сфере информационных технологий (MIT - massachusetts institute of technology)

Выходцы из этого университета, университета Беркли и некоторых других фактически положили основу всему современному IT, на котором стою в том числе и я (Например знаменитый Hadoop был разработан выходцем из MIT, протокол Kerberos который я до сих пор использую в работе - тоже).

https://web.mit.edu/mprat/Public/web/Terminus/Web/main.html

Лично мне в свое время эта игра помога научиться пользоваться линуксом на базовом уровне. Смело могу рекомендовать ее и вам.
🔥51👨‍💻1
👀5
DataSkewer
🗑️ Эти вопросы всегда задают при собесах на должности связанные с Python. 🗑️ Как работает garbage collector и зачем он нужен? Какие механизмы очистки мусора существуют? Python разработчики не заботятся о таких вещах, как освобождение и выделение памяти,…
Разберем фундаментальную, и довольно сложную тему в Python - GIL ⚙️🔩
но перед этим нужно вспомнить немного теории

CPU-bound программы (обработка изображений, умножение матриц, поиск)
I/O-bound программы (связь по сети, обращение к БД, ожидание ввода данных от пользователя)

Процесс - это часть виртуальной памяти и ресурсов, которые операционная система выделяет для выполнения программы.
Каждый процесс выполняется в отдельном адресном пространстве и не может получить доступ к ресурсам другого процесса.
У каждой программы есть как минимум один процесс, а у каждого процесса - минимум один поток, который называют главным.

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

Поток - это отдельная «нить» (поток) выполнения внутри процесса.

ИТАК

В Python и его стандартном интерпретаторе CPython программы выполняются последовательно. Это связано с GIL (Global Interpreter Lock), который ограничивает Python на один запущенный поток в единицу времени в рамках одного процесса. 😢😢😢
(В Go и С++ например это не проблема и там позволительно иметь несколько потоков сразу)

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

Но все не так плохо, многопоточность тем не менее можно эффективно реализовать, каждый раз когда поток вынужден ждать какую либо Input/output операцию, - другие потоки получают шанс получить время на выполнение (это все в происходит за ничтожно маленькое по меркам человека время) и между потоками происходит переключение GIL.
И соответственно для таких задач (I/O bound) многопоточность в Python остается хорошим вариантом.

Но даже для CPU-bound программ всегда остается мультипроцессинг, который правда сильнее нагружает Операционную систему на которой запущенно приложение.

Еще есть вариант для самых сильных и смелых - написать собственное расширение на C для работы с потоками и использовать его соответственно,

Так же можно использовать другие интерпретаторы такие как Jython и IronPython в которых нет GIL.
🔥4
Channel photo updated
Панчлайн нового логотипа канала в том, что на логотипе Hadoop (один из основных инструментов, что я использую в работе) - так же изображен слон.
Из смешного - как гласит легенда, название и логотип хадупа появились так: сын одного из главных разработчиков играл с плюшевой игрушкой по имени "Хадуп", разработчика это зацепило и вот уже более десяти лет другие разработчики по всему миру смотрят на желтого слона.
👏4😱3🔥2
🪲Вчера я совершил свою первую XSS атаку на станции Positive Technologies на ИТ Пикнике, в следующем посте напишу о самом мероприятии, вкратце - мне понравилось, есть разница с прошлым годом.

Но вернемся к теме, итак - XSS(Cross Site Scripting (в английских аббревиатурах зачастую X имеет значение Cross вместо логичного и очевидного "Икс")) и хочу вам рассказать о том, что же это такое.

Простейшая XSS атака выглядела бы так:

Вы вводите в какое-нибудь промт поле (размещение в поисковой строке, в области обратной связи, месте для сообщений/комментариев) данный код

<div>
<img src='x' onerror='alert("Hello XSS")'>
</div>


После попытки сделать импорт изображения из несуществующего источника (стринга х)
сработает обработчик ошибок onerror что и вызовет потенциально вредоносный код, в нашем случае это безобидный поп-ап с текстом "Hello XSS".

Для такого скриптинга используются следующие лазейки в приложениях:

1) Ошибки, сделанные в браузере, например реализация сценария посредством тегов SVG / IMG, при которой появляется возможность не принимать во внимание правило ограниченного домена. Это грубая, заметная ошибка разработчиков, если такая атака пройдет - то сами и виноваты)

2) Проблемы с экранированием. Пока браузеры не научились дифференцировать обыкновенный текст от кода. Для распознавания и реализации команд последнего необходима разметка тегами <noscript></noscript>

3) Замена кодировки в заглавии страницы. Определение кодировок происходит в ходе обработки веба. Она находится в метке <meta>, если <noscript> расположен до нее, то браузер начинает работать с заголовком, после обращает внимание на кодировку. У взломщика появляется шанс обойтись без фильтрации символов <>, “” и поместить в noscript вредоносный скрипт, созданный в формате UTF-7.

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

Простую SQL инъекцию можно сделать вставив текст ниже в какое либо поле. Принцип работы так же основан на плохом/отсутствующем экранировании.

'; DROP TABLE users; --'


На этом сайте вы можете попробовать поотачивать свои навыки в XSS 😄

Так же стоит отметить, что принцип таких XSS Атак отдаленно похож на принцип работы такого инструмента как Google Tag Manager. Поэтому, рекомендую вам копнуть в эту тему глубже если планируете развиваться как Веб-аналитик.

https://xss-game.appspot.com/
👍4🔥2
🔥7👍1👏1
⚡️ ⚡️ ⚡️ Прерываю долгую паузу в ведении канала рассказом об одной из самых крупных ИТ конференций в России - а именно Highload++ 2024.
Строго говоря, тема конференции это высоконагруженные системы - большие данные входят в это множество, но не полностью охватывают его)

Из докладов не относящихся к большим данным но заинтересовавших меня -

1) Когда Powershell лучше, чем Ansible? Рецепты приготовления на 1000+ серверов

2) Бесконечная война в памяти: ретроспектива методов защиты от бинарных угроз

3) Как не деградировать сервису подбора рекламы, когда мир сходит с ума

Буду продолжать держать вас в курсе событий на этой конференции. Длится конференция с 2 по 3
декабря 2024.
🔥31😱1
🔥51🎄1
👽Очень понравился тейк о том что, проблемы высоконагруженных систем решаются на уровне архитектуры, а не на уровне кода (если конечно разработчик не написал настолько плохой код, что тот валит хорошую архитектуру)

Отдельно хочется отметить как часть спикеров очень не любит вдаваться в детали, и на конкретные вопросы о практиках и технологиях - говорят «тут речь шла о методологии, техстек я тут не готов обсуждать - это наши внутренние решения» 🥶🥶🥶

Еще один инсайт - хранилища ВК суммарно держат в себе порядка 1 эксабайт данных.

(На фото - игра со станции Домклик)
🔥4
Замечательный слайд сравнивающий переход от монолита к микросервисам.
😁11😍1💅1
🔆 Вот и подошел к концу Highload++ 2024.
Первый раз был на такой крупной конференции, и я конечно же восхищен.
Вот что я могу сказать, из плюсов

Очень удобный бот конференции в котором можно отслеживать доклады и устроить Random Coffee

Очень широкий спектр тем (от даты до архитектуры, маркетинга и безопасности)

Прекрасный кейтеринг

Куча C-levelов российского бигтеха с которыми можно вживую поговорить и задать вопросы (переборов страх быть кринжовым)

Колоссальные возможности для нетворкинга - я поставил себе цель, познакомиться и обменяться контактами с 10+ специалистами и перевыполнил эту цель в 1.5 раза, без особых усилий.

Из минусов (каинда):

стоит разделить конференцию на фестивальную часть и часть докладов - невозможно физически посетить все доклады и все стенды - я старался держать баланс, но охватил от силы 30 процентов стендов и 20 процентов докладов. (Доклады к тому же шли в параллель)

Звездами этой конференции были PHP и Golang - у меня немного другой стек

Ну и подводя итог, рекомендовал бы посетить эту конференцию, специалистам уровня Middle+
Тк у многих докладов есть неслабый порог вхождения, и вам нужно быть хотя бы специалистом конкретно вашей области + иметь хорошие знания в general computer science (вспоминаем о входителях в айти, говорящих, что алгоритмы, паттерны проектирования и прочая БАЗА никому не нужна) - иначе для вас конференция сведется лишь к фестивальной части.

В следующем посте, на основе данных этой конференции, расскажу о том когда вашему хадупу/S3 стоит задуматься об использовании Apache Iceberg.
🔥5👍2
🔥6👍1