Гепардово гнездо
637 subscribers
41 photos
1 file
81 links
El nido del guepardo.

@gepardius тащит в гнездо всякое интересное из мира программирования (и не только).

Etaoin shrdlu cmfwyp!

Еще один мой канал: @sofcheck.
Download Telegram
Еще в тему шахмат

В этой позиции каждый ход ставит мат, причем вне зависимости от того, ходят белые или черные.

FEN: 6BN/2p2R1P/2Ppk1NR/p2p2PP/p2P2P1/P1KP4/rr6/b7 w - - 0 1

Позиция честно украдена из книги «Шахматы. Полный курс» авторства Н. Калиниченко и В. Линдера.
🔥8🐳1
Как восстановить файл, если кто-то держит на него открытый файловый дескриптор

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

Можно попытаться и восстановить доступ к удаленному файлу: найти его в /proc/<pid>/fd/<fd> и скопировать. Но можно ли обойтись без копирования, а просто восстановить хардлинк на него в файловой системе?

Известно, что ссылка на открытый файл в /proc отображается как символьная ссылка, но на самом деле символьной ссылкой не является. Так, для открытого удаленного файла stat будет выглядеть примерно так:

$ stat /proc/42002/fd/3
Файл: /proc/42002/fd/3 -> /home/gepardo/tmp/q.txt (deleted)
Размер: 64 Блоков: 0 Блок В/В: 1024 символьная ссылка
Устройство: 00h/00d Инода: 000000 Ссылки: 1
Доступ: (0500/lr-x------) Uid: ( 1000/ gepardo) Gid: ( 1000/ gepardo)
Доступ: 2022-11-03 20:46:09.224688879 +0300
Модифицирован: 2022-11-03 20:46:02.440682242 +0300
Изменён: 2022-11-03 20:46:02.440682242 +0300
Создан: -

Теперь попробуем создать хардлинк. Сначала попробуем воспользоваться простой командой ln:
$ ln -T /proc/42002/fd/3 w.txt
ln: не удалось создать жёсткую ссылку 'w.txt' => '/proc/42002/fd/3': Неверная ссылка между устройствами

Не получилось. Но мы непременно попробуем еще в следующем посте :)
👍3
Как восстановить файл, если кто-то держит на него открытый файловый дескриптор (часть II)

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

Пробуем. В Linux есть системный вызов linkat(). Он поддерживает флаги AT_EMPTY_PATH и AT_SYMLINK_FOLLOW, которые позволяют создать хардлинк на файл по файловому дескриптору на него (в том числе по ссылке в /proc/<pid>/fd). На StackOverflow показывают пример, как можно сделать хардлинк по файловому дескриптору:

fd = open("/tmp", O_TMPFILE | O_RDWR, 0600);
// write something to the file here
// fchown() / fchmod() it
linkat(fd, "", AT_FDCWD, "/tmp/test", AT_EMPTY_PATH);

Попробуем так же:
https://pastebin.com/tkyY2abT

Увы, не работает: программа выдает linkat: No such file or directory. Впрочем, man явно предупреждает, что ничего не выйдет, и среди ошибок упоминает

> ENOENT An attempt was made to link to a /proc/self/fd/NN file corresponding to a file that has been deleted.

Вариант с AT_SYMLINK_FOLLOW тоже ничего не дает:
https://pastebin.com/vVz3zcR0

Так что, к сожалению, остается единственный способ — копировать.
😢1
Forwarded from Блог*
#prog #rust

В стандартной библиотеке Rust есть модуль sync::mpsc, который содержит реализацию однонаправленного multiple producer single consumer канала. Если открыть документацию метода принимающей половины канала, Receiver::recv_timout, то можно увидеть раздел "Known issues" про возможность неожиданной при вызове метода, вкупе с кодом для надёжного воспроизведения этой проблемы. И сама документация, и сообщение при панике отсылают на соответствующее issue в репозитории Rust, которому, на минуточку, 5 лет.

Так как тулинг Rust позволяет легко задействовать сторонние зависимости, те, для кого эта проблема была важна, использовали сторонние реализации каналов. Стандартом де-факто стала библиотека crossbeam-channel. После того, как она получила широкое распространение, пошли разговоры о том, чтобы включить реализацию в std — и прецедент для такого уже был с заменой предыдущей реализации HashMap на реализацию из hashbrown. В феврале этого года такой MR был открыт — правда, реализация в силу различных причин была несколько видоизменена — и вот совсем недавно был влит!

Но это ещё не всё. Помимо фикса этого старого бага, crossbeam-channel также в некоторых аспектах превосходил реализацию в std. Главное — то, что, в отличие от варианта из std, это multiple producer multiple consumer канал. А это значит, что в ближайшем будущем mpmc-канал наверняка будет и в std!
👍2
Рекомендую запомнить и не путать :)
👍8
Самый распространенный и часто встречающийся стык двух согласных —
это сочетание согласных ст. Оно встречается примерно в полтора раза чаще, чем следующее по частоте сочетание согласных пр (1.25% против 0.77%). Сочетание ст встречается чаще, чем согласные й, ж, х, ш, щ, ц и ф. Только отдельную букву для уменьшения длины текста сочетанию ст не придумали :\
👍4
Обидно, что реакции в Telegram можно лишь искать в списке, а не набирать, как обычные эмодзи. А то иногда я провожу много времени, чтобы найти подходящую реакцию.

А еще нет раздела, в котором можно смотреть только стандартные реакции. А то они видны только среди недавних и замешаны вместе со всеми остальными :(

Для тех, кто не в курсе набора эмодзи с клавиатуры: попробуйте начать набирать :think или :думаю и посмотрите, что предлагает автодополнение :) И так работает со всеми эмодзи.
👍4🕊2🐳1
Еще в тему автодополнения и Telegram: если вы пользуетесь Telegram Desktop, попробуйте набрать :shrug:. Получится ¯\_(ツ)_/¯
👍3
Я обычный человек и печатаю своими человеческими руками

Оригинал (или вот ссылка на перевод)
😁4👍1🤯1
И еще в тему пауков 🕷🕷🕷
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Про явную специализацию шаблонной функции в С++

Рассмотрим такой код из нескольких файлов.

Файл a.h:
#include <iostream>

template<int N> void doit() { std::cout << 1 << std::endl; }

Файл a.cpp:
#include "a.h"

template<> void doit<1>() { std::cout << 2 << std::endl; }

Файл b.cpp:
#include "a.h"

int main() { doit<1>(); }

Что выдаст код — 1 или 2?

(Правильный ответ с объяснением ждите завтра!)
Что выдаст код?
Final Results
23%
1
23%
2
23%
Неизвестно
32%
🐳
🐳5
Про явную специализацию шаблонной функции в С++, часть 2

Что выдаст код — 1 или 2?

Зависит от настроек линковки!
$ g++ a.cpp b.cpp -o a -fuse-ld=lld && ./a
2
$ g++ -Wl,--start-lib a.cpp b.cpp -Wl,--end-lib -o a -fuse-ld=lld && ./a
1

Почему так получается? Все просто: символы, полученные при явной специализации, являются сильными, а при отсутствии явной специализации — слабыми. В первом случае получается так, что слабый символ перекрывается сильным, и мы получаем 2. Во втором случае (с --start-lib) сильный символ не используется, поскольку линкер видит, что у нас уже есть слабый символ, и игнорирует содержимое a.o, который был получен из a.cpp. Но тогда мы получаем 1.

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

А вообще, судя по StackOverflow, программа попросту некорректна. Цитируя Стандарт C++,
> If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
👍2😱2
Честно украдено с просторов интернетов (увы, не помню, откуда точно)
👍13
Может ли человек генерировать случайные числа независимо и равновероятно?

Попробуйте Aaronson Oracle. Его суть проста: надо нажимать случайно на клавиатуре буквы f и d. А далее простая модель (про ее работу можно почитать здесь) будет пытаться предсказывать вашу следующую букву.

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

Можете считать этот сайт наглядной демонстрацией того, что люди не понимают интуитивно, как должна выглядеть последовательность испытаний Бернулли (т.е. бросков монетки, после которых фиксируется, упала ли монета орлом или решкой)
👍3
Как экстренно оборвать сеанс SSH, не закрывая консоль

Короткий ответ: <Enter>~. (Enter, тильда, точка)

Длинный ответ: ~ включает Escape-последовательности в SSH. До этого надо предварительно нажать Enter. После этого можно вводить команды:
Supported escape sequences:
~. - terminate connection (and any multiplexed sessions)
~B - send a BREAK to the remote system
~C - open a command line
~R - request rekey
~V/v - decrease/increase verbosity (LogLevel)
~^Z - suspend ssh
~# - list forwarded connections
~& - background ssh (when waiting for connections to terminate)
~? - this message
~~ - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

Чтобы выйти из вложенной SSH-сессии, не выходя из текущей, надо набрать <Enter>~~. (Enter, тильда, тильда, точка). Дело в том, что внешняя SSH-сессия преобразует ~~ в ~ и передаст во внутреннюю, а та уже, в свою очередь, спокойно завершится.
👍2
Шахматная задача на сегодня

(см. картинку выше)

Белые начинают и ставят мат.

FEN: 8/8/8/2p5/1pp5/brpp4/qpprpK1P/1nkbn3 w - - 0 1
Забавный Юникод

Угадайте, почему так происходит:
>>> ''.join(reversed('🇧🇬🇦🇲'))
'🇲🇦🇬🇧'

(запускалось в консоли Python)

В чем же дело? Догадки можно писать в комменты, завтра будет ответ.
😁6
Забавный Юникод: объяснение

На самом деле, все предельно просто.

Как известно, в Python строки хранятся в UTF-32, то есть по одному code point'у на один элемент строки. Таким образом, переворот строки происходит на уровне code point'ов.

Но отображение текста работает хитрее — каждый видимый на экране символ необязательно состоит из одного code point'а, может из нескольких. Такая совокупность code point'ов, образующая один видимый символ, называется extended grapheme cluster. Вычисление границ extended grapheme cluster происходит по определенному сложному алгоритму (который еще и дополняется при выходе новых версий Юникода!).

Теперь вернемся к нашим баранам флагам. На самом деле, в числе code point'ов Юникода нет никаких флагов, зато есть 26 специальных «букв» от A до Z. Две такие «буквы» интерпретируются как один extended grapheme cluster, а образовавшийся от них код страны как раз и задает флаг.

Например, строка '🇧🇬🇦🇲' состоит из четырех таких «букв»: BGAM (или 🇧 🇬 🇦 🇲, если у вас «буквы» умеют отображаться по отдельности). При реверсе мы получаем MAGB, где MA составляет 🇲🇦 (Марокко), а GB🇬🇧 (Британию)

Таким образом, загадка разгадана :)
🔥12