Страницы

Поиск по вопросам

понедельник, 16 декабря 2019 г.

Как устроены составные индексы? На примере PostgreSQL.

#postgresql #sql


1) есть 2 поля - varchar 'text' и int 'value'. По ним создан индекс:

CREATE INDEX idx_index_value_and_text
ON index_test ( value, text )

Пишу:

select * from index_test r where
r.text='some value'

Анализатор говорит:

Index Scan using
idx_index_value_and_text on index_test

Вопрос: как он может искать по индексу, если первая колонка не указана? В терминах
 B-Tree - что представляет собой составной индекс: единое дерево, значения нод которого
есть concatenation строк значений входящих в него полей? 
2) Данный поиск в зависимости от распределения значений колонок имеет разные типы:
Bitmap Heap Scan и Bitmap Index Scan, либо Index Scan если распределение достаточное
ровное. Что означают Bitmap-типы, чем отличается Bitmap Index Scan от Index Scan? Кроме
того, есть ли в Postgres Index Range Scan?    


Ответы

Ответ 1



Составной индекс, в отличие от "одинарного" индекса в качестве индексируемого значения использует не одно значение, а несколько значений то есть если есть 2 поля A и B то составной индекс по ним будет выглядеть примерно так: | A | B | --------- | 1 | 1 | | 1 | 2 | | 1 | 4 | | 2 | 2 | | 2 | 3 | | 2 | 5 | Грубо говоря это сортировка по двум полям, а не одному полю. То есть это не индексирование конкатенированных значений A+B. На уровне BTree это выглядит как будто листочки BTree отвечающие за поле A, ссылаются на вложенное дерево BTree отвечающее за поле B. Сканирование индекса в вашем случае фактически означает, что поскольку первое поле у вас не задано, то сервер сканирует все листочки дерева A, чтобы найти подходящее значение поля B. Составной индекс полезен когда информация может быть кластеризована: скажем по этому принципу устроены словари/энциклопедии. Вам нужна статья на букву "Д" - вы находите по оглавлению раздел на букву "Д" и далее ищете нужную статью. А вот если нужна статья заканчивающаяся на "К" - то кластеризация уже не поможет - придется рыться во всей книге (сканировать индекс).

Arc4random не работает как должен

#c #objective_c #случайные_числа


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


в моем конкретном случае стояла задача сделать рандомным выпадение одной из двух
карточек (симуляция выбора из двух игральных карт). При тестировании обнаружилось что
одна карточка выпала 11 (!) раз подряд. При наличии выбора из трех карточек - одна
из них выпала 6 раз подряд. Решил привязаться к миллисекундам времени нажатия клавиши
выбора, и это в целом решило вопрос в более приемлемую сторону. Хочу поинтересоваться
встречается ли данный вопрос у Вас (то есть не паранойя ли у меня) и если да то как
с ним боретесь.

UPDATE:
читая man для arc4random встречаю строки: "...The arc4random() function returns
     pseudo-random numbers in the range of 0 to (2**32)-1, and therefore
     has twice the range of rand(3) and random(3). ..."
То есть все объяснимо, но не понял зачем тогда рандом который не является рандомным
    


Ответы

Ответ 1



Нет, это не паранойя, а общая болезнь многих генераторов. Ваше решение является одним из самых распространенных и в достаточной мере решает проблему. Если же нужно увеличить порядок случайности, то необходимо будет воспользоваться кастомным рандомом, алгоритмы в сети есть, но тут увеличатся накладные расходы. Можете проверить С аналог, может результаты понравятся больше: srand(time(NULL)); int m = rand();

В C++ при наследовании определяется доступность только открытых элементов родителя?

#наследование #ооп #cpp


Прочитав несколько статей по этому поводу не могу сказать, что точно все понял. Такая
конструкция  

class Child : private Parent ...


сделает все публичные элементы родителя приватными у наследника? И так же, если там
указать public или protected, то это влияет только на публичные родительские элементы
или нет?
    


Ответы

Ответ 1



private (закрытый, внутренний член класса) — обращения к члену допускаются только из методов того класса, в котором этот член определён. Любые наследники класса уже не смогут получить доступ к этому члену. Наследование по типу private делает все члены родительского класса (в том числе public и protected) private-членами класса-наследника (С++) protected (защищённый, внутренний член иерархии классов) — обращения к члену допускаются из методов того класса, в котором этот член определён, а также из любых методов его классов-наследников. Наследование по типу protected делает все public-члены родительского класса protected-членами класса-наследника (С++); public (открытый член класса) — обращения к члену допускаются из любого кода. Наследование по типу public не меняет модификаторов родительского класса (С++); Таким образом, ответ на ваш вопрос: class Child : private Parent - да, такое наследование сделает все публичные элементы родителя приватными у наследника.

Выделение памяти С++

#память #cpp


Вопрос достаточно простой, но для меня он неясен.
Всем известно, что в С++ у нас есть несколько способов выделения памяти.
В моем случае у нас есть главный объект приложения. В нем создаются главные части:
объект ядра и объект интерфейса. Мой вопрос состоит в следующем. Каким образом лучше
выделять память под эти объекты.
1 вариант:
GlCore gl_core;
Gui gui;

2 вариант:
GlCore *gl_core;
Gui *gui;

В первом случае я вижу плюсы в том, что не нужно думать о delete и в том, что память
выделиться на этапе запуска приложения. Но я использую wxwidgets и там элементы интерфейса
советуют создавать по второму варианту. Оно ясно, что это чем-то обусловлено, но я
к сожалению не могу понять и сделать для себя какой-то вывод. Мне интересны обоснованные
плюсы в пользу того или иного варианта выделения памяти.    


Ответы

Ответ 1



Вы не должны думать о мелких несущественных технических деталях, наподобие «нужно вызывать delete или сэкономим одну строчку». Не экономьте на спичках. Думайте о смысле. Нужны ли вам объекты gl_core и gui всегда, или вы хотите создать их в какой-то определённый, контролируемый вами момент? Требуют ли они, чтобы что-то было инициализировано до их создания? Если да, глобальный объект — не лучшее место. Требуют ли объекты gl_core и gui подчистить за собой, когда они больше не нужны (например, когда приложение завершает работу графической части)? Если да, вам неплохо бы вызвать деструктор (посредством delete) вручную, а не дожидаться автоматической деаллокации в конце жизни приложения.

Как определить, подключёно ли что-либо в разъём jack на звуковой карте?

#железо #linux


Как определить, заняты ли разъёмы на звуковой карте или нет?

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


Ответы

Ответ 1



согласно вот этому ответу, информацию можно почерпнуть из файлов /proc/asound/card*/codec#*. пример из этого ответа: наушники подключены: $ cat /proc/asound/card0/codec#0 [...] Node 0x0d [Pin Complex] wcaps 0x400181: Stereo Control: name="Speaker Phantom Jack", index=0, device=0 Pincap 0x00000014: OUT Detect Pin Default 0x90170110: [Fixed] Speaker at Int N/A Conn = Analog, Color = Unknown DefAssociation = 0x1, Sequence = 0x0 Misc = NO_PRESENCE Pin-ctls: 0x00: [...] наушники отключены (сравните строки про Pin-ctls): $ cat /proc/asound/card0/codec#0 [...] Node 0x0d [Pin Complex] wcaps 0x400181: Stereo Control: name="Speaker Phantom Jack", index=0, device=0 Pincap 0x00000014: OUT Detect Pin Default 0x90170110: [Fixed] Speaker at Int N/A Conn = Analog, Color = Unknown DefAssociation = 0x1, Sequence = 0x0 Misc = NO_PRESENCE Pin-ctls: 0x40: OUT [...]

Установка Ruby on Rails

#ruby_on_rails


При установке Ruby on rails наткнулся на небольшую проблему. 
Действовал так же, как описано в туториале на http://railstutorial.ru/.
После выполнения gem install rails --version 4.0.0 
попытался запустить rails -v и получил ошибку:
Приложение 'rails' может быть найдено в следующих пакетах:
 * rails
 * ruby-railties-3.2
Попробуйте: sudo apt-get install <выбранный пакет>

Гуглением понял, что необходимо добавить путь до gem:
PATH="${PATH}:~/.rvm/gems/ruby-2.0.0-p576@railstutorial_rails_4_0/bin/"

Снова попробовал запустить rails -v с тем же результатом.  
После чего заметил, что рельсы установились по странному пути, а именно ~/o-ri/.
Перешел туда и запустил напрямую ./rails -v, чем получил ожидаемый результат:
Rails 4.1.6

Казалось бы, вот и решение, но пятая точка подсказывает, что не все так хорошо.
Подскажите, какие проблемы возникнут и как их избежать? Или, может, я накосячил на
каком-то из этапов, и надо все переделать?    


Ответы

Ответ 1



Вы неправильно установили RVM. А возможно, просто забыли перезапустить терминал после установки. Так или иначе, bash не пытается искать команды в директориях гемов RVM. Попробуйте установить его заново и проследите, что необходимые для его работы строчки добавились (в ~/.bashrc, по-моему, но, может, и в ~/.profile).

Как отучить Yii2 удалять cookie?

#php #cookie #yii2


Суть:
Yii2 все куки и сессии удаляет через некоторое время, хотя время жизни 3600*24*30*12
- что подтверждается при просмотре кук в браузере.
Удаляет и PHPSESSID и любые другие на домене

Мой конфиг:

'session' => [
            'class' => 'yii\web\Session',
            'cookieParams' => ['httponly' => true, 'lifetime' => 3600*24*30*12],
            'timeout' => 3600*24*30*12,
            'useCookies' => true,
        ],
'request' => [
            'enableCookieValidation' => false,
            'enableCsrfValidation' => true,
            'cookieValidationKey' => 'секретка',
        ],


Валидацию отключил т.к. пробовал задавать через setcookie напрямую.
Момент удаления отследить не смог, но он наступает через какое-то время после неактивности
клиента, примерно 20 минут.

Так же выяснил что удаляются все куки, если удалить вручную PHPSESSID.
    


Ответы

Ответ 1



Возможно дело не в yii. Такое поведение встречается из-за неверного или отсутствующего значения параметра session.cookie_domain php.ini, который можно установить: session.cookie_domain = ".site.com" Или: ini_set('session.cookie_domain', '.site.com' );