Kristina K creaturek

Несколько слов о безнадзорных животных в Беларуси

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

Например, метод, который сейчас используется для сокращения численности животных, - это не рекомендуемая HSUS эвтаназия [1] с использованием пентобарбитала (который сейчас, кстати, хотят разрешить [2] использовать больным неизлечивыми заболеваниями на последних стадиях), а умерщвление, то есть отстрел [3] при полном сохранении сознания и болевой реакции. Помимо того, что этот способ нельзя признать цивилизованным, подход при отсутствии должного контроля содержания и разведения домашних животных не помогает при условиях, когда увеличившаяся кормовая база и уменьшение ответственности владельцев способствуют росту численности “лишних” котов и собак [4]. Иными словами, идет бесконечная борьба со следствием, а не причиной.

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

Я думаю, что решить проблему без общего осознания важности жизни и ее качества в целом нельзя. Как выступать против уничтожения собак и котов в стране, где расстреливают людей? Можно ли повысить осознанность граждан в отношении своих питомцев, если собственная жизнь воспринимается как выживание? Как было уже сказано: “The greatness of a nation and its moral progress can be judged by the way its animals are treated”.

К счастью, всегда найдутся люди, которые cвоими действиями вносят вклад в изменение всей системы. Может быть это вы?

Помочь можно как материально, так и через волонтерскую работу. А еще можно взять котейку или собакена себе; жизнь становится в разы лучше, подтверждаю лично:

  • Общественное Объединение Защиты Животных “Эгида”: http://egida.by
  • Приют “Суперкот”: http://superkot.com
  • Международное благотворительное объединение помощи животным “Зоошанс”: http://zooshans.by

1. The HSUS - Euthanasia Reference Manual
2. Paul Komesaroff - We don’t need greater access to Nembutal to achieve good end-of-life care
3. Положения о порядке деятельности организаций по отлову, отстрелу, содержанию и эвтаназии безнадзорных животных в Республике Беларусь
4. Регулирование численности безнадзорных и бездомных собак и кошек – мировой опыт. Варианты для России.

Cинхронность отправки и получения данных по небуферизированным каналам в Go

Листала книгу, в которой пригляделся пример с небуферизированными каналами:

alt text alt text

Эмулируется игра в теннис с двумя игроками. Игрок представлен горутиной, которая читывают и записывают в канал значение (перекидывание мячика). Вывод был следующий:

alt text

Резонно возникает вопрос: можно ли быть уверенным в том, что значение, которая передала первая горутина (строка 32), прочитает вторая горутина (строка 45), а не та же, что и отправила? Иными сломами, может ли возникнуть ситуация, при которой вывод программы будет следующий:

Player Nahal Hit 1
Player Djokovic 2 
Player Nahal Hit 3
Player Nahal Hit 4 // здесь горутина, готорая отправила "мячик", его же и получила
Player Djokovic 5

Вооруживщись отсылкой к авторитетам с предположением, что автор книги более компетентен, я начала размышлять, по какой причине так уверенно было реализовано чтение и запись в одной функции без боязни незапланированного чтения значения одной и той же горутиной. Первой мыслью было детерминированная последовательная передача ресурсов из канала планировщиком горутинам в последовательности, как они “были зарегестрированы” на получение данных. То есть если вторая горутина первая встала в очерeдь на чтение, то при записи однозначно ей будет переданы данные на чтение. Эта версия, однако, весьма сомнительная, потому что в буферизированных каналах чтение и запись из канала планировщик осуществляет в случайном порядке (для примера достаточен любой код с несколькими горутинами и capacity канала больше, чем 1, хоть этот).

Ответ гораздо красивее: запись в небуферизированый канал выполняется синхронно с чтением. Даже так: CSP Go работает таким образом, что чтение в канал (но только небуферизированный) выполняется раньше, чем заканчивается запись. Для нас это значит, что в тот момент, когда первая горутина отправила в значение (строка 32), она заблокировалась. Так что мячик в любом случае принимает вторая горутина (второй игрок) и все работает как и предполагалось.

Отличная иллюстрация поведения канала (а именно: его блокировки до момента чтения) из [3]:

alt text

Подробнее:

  1. Самое простое - внимательно читать книги, а не рывками хватать информацию, в Go action это также упомянуто.
  2. Официальная документация
  3. The Nature Of Channels In Go
  4. Are waiting sends to an unbuffer channel ordered - Google groups

Православный способ преобразования текстового файла из одного формата в другой

В связи с тем, что через несколько месяцев надо сдавать диплом, резко встал вопрос о безболезненном переносе документов в разные офисные программы. Конечно, для такого серьезного документа - с таблицами, ГОСами и проверками отступов линейкой - безопаснее использовать LaTeX. Однако для небольших и средне-простых в оформлении файлов будет полезна утилитка Pandoc.

Так, для конвертации из файла md в pdf (программка умеет работать чуть ли не со всеми известными форматами) выполним команду:

pandoc cv.md -o cv.pdf

Вуаля!

Корректное восстановление соединения на GO

Не так давно О. рассказывал, что у них на работе в очередной раз хотят уволить сотрудника. “Не справляется,” - ответил он на вопрос о причине. И добавил, что чел не смог написать код сохранения в базу с retry policy”.

Ввиду моей феноменально “идеальной” памяти делаю заметку.

    var secToRecon = time.Duration(time.Second * 2) // стартовое время реконнекта
    var numOfRecon = 0 //  номер реконнекта

    for {
        ln, err = net.Listen(network, linkD.address) // пытаемся запустить ожидание сетевого подключения
        if err == nil {
            // функция выполнилаcь корректно - можно выйти из цикла и продолжить исполнение кода
            fmt.Prinln("Listen OK")
            break
        }
        
        // функция вернула ошибку! пытаемся переподключиться
        fmt.Prinln("Listen errorr!", err.Error())
        
        // создаем тикер (таймер, который сигнализирует не один раз, а каждые secToRecon)
        ticker := time.NewTicker(secToRecon)

        select {
        case _ = <-ticker.C:
            {
                /* 
                 время переподключения не меньше установленного лимита - изменяем его:
                 увеличиваем задержку экспоненциально + 20-30% от текущего времени переподключения
                */
                if secToRecon < backOffLimit {
                    //randomAdd := int(r1.Float64()*(float64(secToRecon)*0.1) + 0.2*float64(secToRecon))
                    randomAdd := secToRecon / 100 * (20 + time.Duration(r1.Int31n(10)))
                    fmt.Printfd("Random addition=%d", randomAdd/1000000)
                    secToRecon = secToRecon*2 + time.Duration(randomAdd)
                    fmt.Printfd("secToRecon=%d", secToRecon/1000000)
                    //  увеличиваем количество переподключений
                    numOfRecon++
                }
                //  инициализируем тикер с новым значением задержки
                ticker = time.NewTicker(secToRecon)
                continue
            }
        }
     }
     

Основные тезисы: время переподключения увеличивается по экспоненциальному закону + случайное число в пределах 10-20% от этого значения (для избежания одномоментной попытки создать подключение - здесь не так очевидно, однако в ряде случаев очень полезно).

Здесь можно посмотреть применение кода в проекте.