← На главную

Мини заметки – выпуск 11

Темы выпуска: объединение нескольких Git-репозиториев с сохранением истории коммитов, управление свопом в Linux, вывод дерева процессов в Erlang, определение объема памяти, занимаемого контейнерами в Scala, и не только. Предыдущие выпуски: десятый, девятый, восьмой, седьмой.

1. Открыл для себя Vagrant

Vagrant – это такой инструмент для управления виртуальными машинами. С его помощью вы можете быстро создать dev-окружение, а затем установить в нем требуемые СУБД, компилятор языка программирования и тд. Все это для того, чтобы не засорять хост-систему.

Идем на http://downloads.vagrantup.com/, выбираем версию Vagrant, качаем и устанавливаем пакет для вашей системы. Затем скачиваем, устанавливаем и запускаем образ гостевой ОС:

vagrant box add precise64 http://files.vagrantup.com/precise64.box vagrant init precise64 vagrant up

Заходим в гостевую систему по SSH:

vagrant ssh

Попадаем в самую обычную Ubuntu 12.10 x64, работающую под VirtualBox.

2. Сколько памяти требуется для хранения списка в Scala?

Создаем файл memusage.scala со следующим кодом:

object Application extends App { val runtime = Runtime.getRuntime() def getMemory() = runtime.totalMemory() - runtime.freeMemory() val count = 1000000 val start = getMemory() var lst = List[Int](); for(t <- 1 to count) lst = t :: lst val end = getMemory() println("Approximate cell size: " + (end - start).toDouble / count) }

Компилируем-запускаем:

scalac memusage.scala scala -cp . Application

На моей машине (x64) получилось, что на один элемент списка тратится примерно 39 байт оперативной памяти. Хотя, учитывая представление списков в Scala, должно быть 8 байт под указатель на следующий элемент списка, 8 байт под указатель на данные и 4 байта под Int, итого 20 байт. Несоответствие можно объяснить боксингом, а также необходимостью поддержания структур данных, используемых сборщиком мусора.

Такое неэкономное использование памяти характерно не только для Scala, но и для других современных высокоуровневых языков программирования. Просто, если вы пишите на одном из этих языков, для вас это не должно быть сюрпризом.

3. Управление swap’ом в Ubuntu

Информация о свопах:

swapon -s

Выключить своп:

sudo swapoff -a

Включить своп:

sudo swapon -a

Уменьшить агрессивность свопинга:

sudo sysctl vm.swappiness=10

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

В Linux переменные sysctl прописываются в /etc/sysctl.conf.

4. Как написать анонимную рекурсивную функцию на Scala

Тут весьма кстати приходится тот факт, что функции в Scala являются объектами:

val fact = new Function1[Int,Int] { def apply(x:Int):Int = if(x==1) x else x * apply(x-1) }

Взято со StackOverflow.

5. Настройка xinetd в Ubuntu

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

Устанавливаем xinetd:

sudo aptitude install xinetd

Создаем сценарий /usr/bin/xinetd-test следующего содержания:

#!/usr/bin/env perl use strict; use warnings; $| = 1; print "Hello. What is your name?\n"; my $name = <STDIN>; $name =~ s/[\r\n]//g; print "Nice to meet you, $name!\n";

Говорим:

sudo chmod a+x /usr/bin/xinetd-test

В файл /etc/services дописываем:

elite 31337/tcp

В /etc/xinetd.conf добавляем:

service elite { socket_type = stream protocol = tcp wait = no user = eax server = /usr/bin/xinetd-test instances = 20 }

Перезапускаем xinetd:

sudo service xinetd restart

Теперь telnet’имся к порту 31337.

6. Как получить список уязвимостей в используемом ядре Linux

Как вы считаете, много ли дыр имеет используемое вами в данный момент ядро Linux? Запишите вашу оценку на бумажке, а затем выполните команду:

(uname -s; uname -m; uname -r; uname -v) | \ curl https://uptrack.api.ksplice.com/api/1/update-list/ \ -L -H "Accept: text/text" --data-binary @-

Однострочник украден с OpenNet. Подробности о Ksplice и обновление ядра Linux на лету можно прочитать здесь.

7. Сидим в Skype с двух аккаунтов

Знаете ли вы, что в Skype можно сидеть с нескольких аккаунтов одновременно?

Команда:

skype --secondary

… в Linux и:

skype.exe /secondary

… в Windows запускает второй экземпляр Skype, в котором вы можете залогиниться под другим аккаунтом. Например, в одном Скайпе у вас может быть личный аккаунт, а во втором – рабочий.

8. Вывод дерева процессов в Erlang

Следующий код, выполненный в консоли Erlang’а, выводит дерево процессов:

P = fun(Supervisor, supervisor, SupPid, S) -> { Supervisor, supervisor, [ S(Mod, Type, Pid, S) || {Mod, Pid, Type, _} <- supervisor:which_children(SupPid) ] }; (Module, Type, _Pid, _Self) -> { Module, Type, [] } end. P(main_sup, supervisor, whereis(main_sup), P).

Здесь main_sup – имя супервизора, с которого начнется построение дерева.

9. Как в Linux изменить заголовок окна терминала

Следующая команда позволяет установить произвольный заголовок окна терминала:

echo -ne "\033]0;your title here\007"

При желании можно замутить скрипт или, возможно, алиас.

10. Объединение репозиториев без потери истории коммитов

Есть репозиторий dependency, который нужно полностью переместить в каталог apps репозитория project, сохранив при этом историю коммитов. В обоих репозиториях разработка ведется в ветках под названием dev.

cd ~/temp git clone git@bitbucket.org:afiskon/dependency.git cd dependency git checkout dev git remote rm origin mkdir -p apps/dependency mv * apps/dependency mv .gitignore apps/dependency git add . git commit -am 'prepared for merging into project repository' cd .. git clone git@bitbucket.org:afiskon/project.git cd project git checkout dev git remote add dependency_remote ../dependency git pull dependency_remote dev git remote rm dependency_remote git commit -am 'dependency is now placed in ./apps' git push origin HEAD

В действительности, все это происходило с проектом, написанным на Erlang, в связи с чем требовались также правки rebar.config, размещение файлов .gitkeep в каталогах ebin, а также еще что-то, о чем я, к сожалению, уже позабыл.

Дополнение: Мини-заметки – выпуск 12