Около it
289 subscribers
1K photos
219 videos
36 files
362 links
Складчина одного программиста.
Задерживаем развитие с 22.12.2017

Материалы и статьи сюда разные закидываю. Личное, интересное, неинтересное.
Программирование, администрирование, то-сё, пятое, десятое.
В основном непутёвые заметки.

Чат - @okoloit_talk
Download Telegram
Попутно еще сервис по конвертированию сюда вкину чтобы не забыть.
Удобно, быстро, качественно. Побольше бы такого
https://convertio.co/
Кто бы мог подумать.
Оказывается, московский музей Дарвина имеет свой аккаунт на скетчфаб. Отсканированы более 260 позиций с хорошим описанием. Посмотреть/покрутить тут
https://sketchfab.com/darwinmuseum.ru/models
Оу, оказывается у Smithsonian есть нечто подобное.
https://3d.si.edu/explore
Тут можно и на перчатки экипажа Apollo 11 посмотреть (или даже распечатать).
Тут даже слепок лица Линкольна есть. ЧОТКА
Для галочки в голове
Forwarded from Doque Embedded
По мотивам вчерашнего обсуждения в https://t.me/theyforcedme/2895

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

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

void foo(){
// выделяем память
DataType* data = malloc(sizeof(Data));

// работаем с памятью
process(data);

// освобождаем память
free(data);
}

Пока что все выглядит ок. Но требования меняются, и теперь нам надо обрабатывать данные в зависимости от того что вернула предыдущая обработка.

void foo(){
DataType* data = malloc(sizeof(Data));

if(process_1(data)){
if(process_2(data)){
if(process_3(data)){
process_4(data);
}
}
}

free(data);
}

Цикломатическая сложность растет, и если мы продолжим писать в этом же стиле - рано или поздно мы уйдем ifами за правый край экрана (ну или запутаемся в блоках). Код становится неприятно читать и сложно поддерживать, давайте его перепишем на множественный возврат из функции.

void foo(){
DataType* data = malloc(sizeof(Data));

if(!process_1(data)){
free(data);
return;
}

if(!process_2(data)){
free(data);
return;
}

if(!process_3(data)){
free(data);
return;
}

process_4(data);

free(data);
}

Это выглядит и читается приемлимо, но поддерживать этот код стало еще сложнее, например очень легко можно забыть освободить память перед возвратом. Для борьбы с этим человечество придумало блоки finally и идиому "Получение ресурса есть инициализация" (RAII). К сожалению мы любим простреленные ноги и пишем на языке Си, в котором подобное невозможно реализовать не превратив код обмазанный макросами в некрономикоподобный диалект. Что же мы можем сделать?

void foo(){
DataType* data = malloc(sizeof(Data));

if(!process_1(data)) goto finally;
if(!process_2(data)) goto finally;
if(!process_3(data)) goto finally;
process_4(data);

finally:
free(data);
}

К сожалению столь лаконичный код получился с использованием goto. Использование оператора goto в целом критикуется, так как программу с его использованием читать на порядки сложнее, как минимум неявны начала и концы переходов, для подробной критики см "Go To Statement Considered Harmful" Эдсгера Дейкстры. Нам нужен блок который бы исполнялся один раз и из которого мы можем выйти оператором отличным от goto, например возьмем отдельную функцию.

void process_data(DataType* data){
assert(data);

if(!process_1(data)) return;
if(!process_2(data)) return;
if(!process_3(data)) return;
process_4(data);
}

void foo(){
DataType* data = malloc(sizeof(Data));
process_data(data);
free(data);
}

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

Чтобы не отвлекать программиста на другие функции мы можем использовать что-то наподобие "анонимной функции", например цикл из одной итерации. Цикл из одной итерации может быть любого вида, while, for, но do {} while (false); это довольно распространенная и понятная идиома, не требующая дополнительных переменных.

void foo(){
DataType* data = malloc(sizeof(Data));

do {
if(!process_1(data)) break;
if(!process_2(data)) break;
if(!process_3(data)) break;
process_4(data);
} while(false);

free(data);
}

В результате мы получили идиому которая явно указывает начало-конец перехода, выделяет блоком код который можно менять не отвлекаясь на освобождение ресурса, и в целом код который довольно лаконично выглядит.
Ну собсна
Forwarded from 112
Российского хакера Павла Ситникова вызвали на допрос после обысков в Group-IB.

Известно, что у Ситникова был конфликт с основателем компании Ильей Сачковым, который накануне был арестован по делу о госизмене.
Тут же явно кому-то не хватало кнопок с фразами из мемасов, по этому добавлю тоже сюда
https://www.myinstants.com/categories/memes/
Тут у notion появился промокод для стартапов - ADALOVELACE
Работает для всех. На счет получаете 500$ (при стоимости годовой подписки в 50$)
Вероятно, у кого-то есть знания java и непомерное желание попробовать себя в разработке приложений под Android.
Отличный экскурс для понимания основы и первого пинка. Страница обновляется.
https://metanit.com/java/android/
КРАСЕВО
Forwarded from iggisv9t channel
Порисовал пикселей вот в такой штуке
https://wiki.xxiivv.com/site/noodle.html