-Поиск по дневнику

Поиск сообщений в rss_rss_hh_new

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 51

Habrahabr/New








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/new/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-new-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

[Перевод] R и большие данные: использование Replyr

Суббота, 29 Июля 2017 г. 15:37 + в цитатник
replyr — сокращение от REmote PLYing of big data for R (удаленная обработка больших данных в R).

Почему стоит попробовать replyr? Потому что он позволяет применять стандартные рабочие подходы к удаленным данным (базы данных или Spark).

Можно работать так же, как и с локальным data.frame. replyr предоставляет такие возможности:
  • Обобщение данных: replyr_summary().
  • Объединение таблиц: replyr_union_all().
  • Связывание таблиц по строкам: replyr_bind_rows().
  • Использование функций разделения, объединения, комбинирования (dplyr::do()): replyr_split(), replyr::gapply().
  • Аггрегирование/распределение: replyr_moveValuesToRows() / replyr_moveValuesToColumns().
  • Отслеживание промежуточных результатов.
  • Контроллер объединений.

Скорее всего, вы всё это делаете с данными локально, поэтому такие возможности сделают работу со Spark и sparklyr гораздо легче.

replyr — продукт коллективного опыта использования R в прикладных решениях для многих клиентов, сбора обратной связи и исправления недостатков.

Примеры ниже.

Все сейчас быстро меняется, поэтому воспользуемся для примеров версиями пакетов в разработке.
base::date()

## [1] "Thu Jul  6 15:56:28 2017"

# devtools::install_github('rstudio/sparklyr')
# devtools::install_github('tidyverse/dplyr')
# devtools::install_github('tidyverse/dbplyr')
# install.packages("replyr")
suppressPackageStartupMessages(library("dplyr"))
packageVersion("dplyr")

## [1] '0.7.1.9000'

packageVersion("dbplyr")

## [1] '1.1.0.9000'

library("tidyr")
packageVersion("tidyr")

## [1] '0.6.3'

library("replyr")
packageVersion("replyr")

## [1] '0.4.2'

suppressPackageStartupMessages(library("sparklyr"))
packageVersion("sparklyr")

## [1] '0.5.6.9012'

# больше памяти, чем предполагается в https://github.com/rstudio/sparklyr/issues/783
config <- spark_config()
config[["sparklyr.shell.driver-memory"]] <- "8G"
sc <- sparklyr::spark_connect(version='2.1.0', 
                              hadoop_version = '2.7',
                              master = "local",
                              config = config)

Summary


Стандартные summary() и glance(), которые нельзя выполнить на Spark.
mtcars_spark <- copy_to(sc, mtcars)

# резюме обработки, а не данных
summary(mtcars_spark)

##     Length Class          Mode
## src 1      src_spark      list
## ops 2      op_base_remote list

packageVersion("broom")

## [1] '0.4.2'

broom::glance(mtcars_spark)

## Error: glance doesn't know how to deal with data of class tbl_sparktbl_sqltbl_lazytbl

replyr_summary работает.
replyr_summary(mtcars_spark) %>%
  select(-lexmin, -lexmax, -nunique, -index)

##    column   class nrows nna    min     max       mean          sd
## 1     mpg numeric    32   0 10.400  33.900  20.090625   6.0269481
## 2     cyl numeric    32   0  4.000   8.000   6.187500   1.7859216
## 3    disp numeric    32   0 71.100 472.000 230.721875 123.9386938
## 4      hp numeric    32   0 52.000 335.000 146.687500  68.5628685
## 5    drat numeric    32   0  2.760   4.930   3.596563   0.5346787
## 6      wt numeric    32   0  1.513   5.424   3.217250   0.9784574
## 7    qsec numeric    32   0 14.500  22.900  17.848750   1.7869432
## 8      vs numeric    32   0  0.000   1.000   0.437500   0.5040161
## 9      am numeric    32   0  0.000   1.000   0.406250   0.4989909
## 10   gear numeric    32   0  3.000   5.000   3.687500   0.7378041
## 11   carb numeric    32   0  1.000   8.000   2.812500   1.6152000

Аггрегирование/распределение


tidyr работает в основном с локальными данными.
mtcars2 <- mtcars %>%
  mutate(car = row.names(mtcars)) %>%
  copy_to(sc, ., 'mtcars2')

# ошибки
mtcars2 %>% 
  tidyr::gather('fact', 'value')

## Error in UseMethod("gather_"): no applicable method for 'gather_' applied to an object of class "c('tbl_spark', 'tbl_sql', 'tbl_lazy', 'tbl')"

mtcars2 %>%
  replyr_moveValuesToRows(nameForNewKeyColumn= 'fact', 
                          nameForNewValueColumn= 'value', 
                          columnsToTakeFrom= colnames(mtcars),
                          nameForNewClassColumn= 'class') %>%
  arrange(car, fact)

## # Source:     lazy query [?? x 4]
## # Database:   spark_connection
## # Ordered by: car, fact
##            car  fact  value   class
##                
##  1 AMC Javelin    am   0.00 numeric
##  2 AMC Javelin  carb   2.00 numeric
##  3 AMC Javelin   cyl   8.00 numeric
##  4 AMC Javelin  disp 304.00 numeric
##  5 AMC Javelin  drat   3.15 numeric
##  6 AMC Javelin  gear   3.00 numeric
##  7 AMC Javelin    hp 150.00 numeric
##  8 AMC Javelin   mpg  15.20 numeric
##  9 AMC Javelin  qsec  17.30 numeric
## 10 AMC Javelin    vs   0.00 numeric
## # ... with 342 more rows

Связывание по строкам


dplyr bind_rows, union и union_all сейчас неприменимы в Spark. replyr::replyr_union_all() и replyr::replyr_bind_rows() — работоспособная альтернатива.

bind_rows()


db1 <- copy_to(sc, 
               data.frame(x=1:2, y=c('a','b'), 
                          stringsAsFactors=FALSE),
               name='db1')
db2 <- copy_to(sc, 
               data.frame(y=c('c','d'), x=3:4, 
                          stringsAsFactors=FALSE),
               name='db2')

# Ошибки из-за попытки осуществить операцию над обработчиком, а не данными
bind_rows(list(db1, db2))

## Error in bind_rows_(x, .id): Argument 1 must be a data frame or a named atomic vector, not a tbl_spark/tbl_sql/tbl_lazy/tbl

union_all


# игнорирует названия столбцов и приводит все данные к строкам
union_all(db1, db2)

## # Source:   lazy query [?? x 2]
## # Database: spark_connection
##       x     y
##    
## 1     1     a
## 2     2     b
## 3     3     c
## 4     4     d

union


# игнорирует названия столбцов и приводит все данные к строкам
# скорее всего, также потеряет дублирующиеся строки
union(db1, db2)

## # Source:   lazy query [?? x 2]
## # Database: spark_connection
##       x     y
##    
## 1     4     d
## 2     1     a
## 3     3     c
## 4     2     b

replyr_bind_rows


replyr::replyr_bind_rows может связывать вместе несколько data.frame-ов.
replyr_bind_rows(list(db1, db2))

## # Source:   table [?? x 2]
## # Database: spark_connection
##       x     y
##    
## 1     1     a
## 2     2     b
## 3     3     c
## 4     4     d

dplyr::do


В нашем примере просто возьмем по нескольку строк из каждой группы аггрегированного набора данных. Обратите внимание: поскольку мы не задаем порядок в явном виде с помощью arrange, нельзя всегда ожидать совпадения результатов в разных источниках данных (БД или Spark).

dplyr::do на локальных данных


Из help('do', package='dplyr'):
by_cyl <- group_by(mtcars, cyl)
do(by_cyl, head(., 2))

## # A tibble: 6 x 11
## # Groups:   cyl [3]
##     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##             
## 1  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4     1
## 2  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2
## 3  21.0     6 160.0   110  3.90 2.620 16.46     0     1     4     4
## 4  21.0     6 160.0   110  3.90 2.875 17.02     0     1     4     4
## 5  18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2
## 6  14.3     8 360.0   245  3.21 3.570 15.84     0     0     3     4

dplyr::do на Spark


by_cyl <- group_by(mtcars_spark, cyl)
do(by_cyl, head(., 2))

## # A tibble: 3 x 2
##     cyl     V2
##    
## 1     6 
## 2     4 
## 3     8 

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

replyr разделение/объединение


mtcars_spark %>%
  replyr_split('cyl', 
               partitionMethod = 'extract') %>%
  lapply(function(di) head(di, 2)) %>%
  replyr_bind_rows()

## # Source:   table [?? x 11]
## # Database: spark_connection
##     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##             
## 1  21.0     6 160.0   110  3.90 2.620 16.46     0     1     4     4
## 2  21.0     6 160.0   110  3.90 2.875 17.02     0     1     4     4
## 3  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4     1
## 4  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2
## 5  18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2
## 6  14.3     8 360.0   245  3.21 3.570 15.84     0     0     3     4

replyr gapply


mtcars_spark %>%
  gapply('cyl',
         partitionMethod = 'extract',
         function(di) head(di, 2))

## # Source:   table [?? x 11]
## # Database: spark_connection
##     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##             
## 1  21.0     6 160.0   110  3.90 2.620 16.46     0     1     4     4
## 2  21.0     6 160.0   110  3.90 2.875 17.02     0     1     4     4
## 3  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4     1
## 4  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2
## 5  18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2
## 6  14.3     8 360.0   245  3.21 3.570 15.84     0     0     3     4

replyr::replyr_apply_f_mapped


Что хотелось бы получить: данные с именами, соответствующими коду (т.е. изменить данные, а не код).

По некоторому размышлению этого можно достигнуть, если связать изменение данных с окружением функции, а не с данными. То есть данные изменены до тех пор, пока соответствующая контролирующая функция выполняется. В нашем случае эта функция — replyr::replyr_apply_f_mapped(), и работает она следующим образом.

Предположим, что операция, которую мы хотим использовать — функция понижения порядка, полученная из некоторого неподконтрольного нам источника (например, пакета). Это может быть простая функция (как ниже), но предположим, мы хотим использовать ее без изменений (исключая даже совсем небольшие, как введение wrapr::let()).
# внешняя функция с заданными в явном виде названиями столбцов
DecreaseRankColumnByOne <- function(d) {
  d$RankColumn <- d$RankColumn - 1
  d
}

Чтобы применить эту функцию к d (в котором не такие, как ожидается, названия столбцов!), мы используем replyr::replyr_apply_f_mapped() для создания нового параметризированного адаптера:
# наши данные
d <- data.frame(Sepal_Length = c(5.8,5.7),
                Sepal_Width = c(4.0,4.4),
                Species = 'setosa',
                rank = c(1,2))

# обработчик для ввода параметров
DecreaseRankColumnByOneNamed <- function(d, ColName) {
  replyr::replyr_apply_f_mapped(d, 
                                f = DecreaseRankColumnByOne, 
                                nmap = c(RankColumn = ColName),
                                restrictMapIn = FALSE, 
                                restrictMapOut = FALSE)
}

# использование
dF <- DecreaseRankColumnByOneNamed(d, 'rank')
print(dF)

##   Sepal_Length Sepal_Width Species rank
## 1          5.8         4.0  setosa    0
## 2          5.7         4.4  setosa    1

replyr::replyr_apply_f_mapped() переименовывает столбцы так, как ожидается в DecreaseRankColumnByOne (соответствие задано в nmap), применяет DecreaseRankColumnByOne и возвращает имена к исходным перед тем, как вернуть результат.

Отслеживание промежуточных результатов


Многие задачи в Sparklyr связаны с созданием промежуточных или временных таблиц. Это можно делать с помощью dplyr::copy_to() и dplyr::compute(). Эти способы могут быть ресурсоёмкими.

В replyr есть функции, позволяющие держать процесс под контролем: генераторы временных имен, не изменяющие собственно данные (они также используются внутри самого пакета).

Сама по себе функция довольно проста:
print(replyr::makeTempNameGenerator)

## function (prefix, suffix = NULL) 
## {
##     force(prefix)
##     if ((length(prefix) != 1) || (!is.character(prefix))) {
##         stop("repyr::makeTempNameGenerator prefix must be a string")
##     }
##     if (is.null(suffix)) {
##         alphabet <- c(letters, toupper(letters), as.character(0:9))
##         suffix <- paste(base::sample(alphabet, size = 20, replace = TRUE), 
##             collapse = "")
##     }
##     count <- 0
##     nameList <- list()
##     function(..., peek = FALSE, dumpList = FALSE, remove = NULL) {
##         if (length(list(...)) > 0) {
##             stop("replyr::makeTempNameGenerator tempname generate unexpected argument")
##         }
##         if (peek) {
##             return(names(nameList))
##         }
##         if (dumpList) {
##             v <- names(nameList)
##             nameList <<- list()
##             return(v)
##         }
##         if (!is.null(remove)) {
##             victims <- intersect(remove, names(nameList))
##             nameList[victims] <<- NULL
##             return(victims)
##         }
##         nm <- paste(prefix, suffix, sprintf("%010d", count), 
##             sep = "_")
##         nameList[[nm]] <<- 1
##         count <<- count + 1
##         nm
##     }
## }
## 
## 

Например, чтобы объединить несколько таблиц, хорошее решение для некоторых источников данных — вызывать compute после каждого объединения (иначе полученный SQL может стать длинным и трудным для понимания и в поддержке). Код выглядит примерно так:
# создание данных для примера
names <- paste('table', 1:5, sep='_')
tables <- lapply(names, 
                 function(ni) {
                   di <- data.frame(key= 1:3)
                   di[[paste('val',ni,sep='_')]] <- runif(nrow(di))
                   copy_to(sc, di, ni)
                 })

# собственный генератор временных имён
tmpNamGen <- replyr::makeTempNameGenerator('JOINTMP')

# объединение слева таблиц в последовательности
joined <- tables[[1]]
for(i in seq(2,length(tables))) {
  ti <- tables[[i]]
  if(icode>

Аккуратное введение и управление временными данными может сохранить ресурсы (и время, и место) и значительно улучшить результаты. Нам кажется хорошей практикой задавать в явном виде генератор временных имён, передавать его во все преобразования Sparklyr, а затем очищать временные значения все вместе, когда результаты от них больше не зависят.

Заключение


Если вы хотите тщательно контролировать обработку данных в Spark или БД с помощью R, стоит рассмотреть replyr в дополнение к dplyr и sparklyr.
sparklyr::spark_disconnect(sc)
rm(list=ls())
gc()

##           used (Mb) gc trigger (Mb) max used (Mb)
## Ncells  821292 43.9    1442291 77.1  1168576 62.5
## Vcells 1364897 10.5    2552219 19.5  1694265 13.0
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334398/


Метки:  

Взлом казино через умный аквариум и DDoS биржевых брокеров: новые атаки на сферу финансов

Суббота, 29 Июля 2017 г. 14:09 + в цитатник


Хакеры продолжают атаковать сферу финансов, и нападения становятся все изощренней. Так, в сеть одного из американских казино киберпреступники проникли через «умный» аквариум, а в начале июля хакеры сначала шантажировали, а потом и атаковали брокеров в Малайзии.

Нападение на аквариум


«Умная» техника становится всё большим источником опасности. О необычном инциденте с таким устройством сообщила в своем отчете американская компания Darktrace, специализирующаяся на кибербезопасности.

Атаке подверглось одно из американских казино. Проникнуть в его сеть преступники смогли через «умный» аквариум, который игорное заведение установило для развлечения гостей. Аквариум с помощью специальных сенсоров регулирует температуру и соленость воды, а также кормит рыбок в автоматическом режиме.

Руководство заведения выделило для коммуникаций аквариума VPN-соединение, изолированное от финансовой сети. Тем не менее, когда устройство проверила система обнаружения угроз от Darktrace, были выявлены аномальные трансферы данных.
В частности, оказалось, что аквариум передает информацию на некое устройство в Финляндии. Больше ни один из компонентов сети казино с ним не сообщается, что и позволило обнаружить хакерскую атаку.

Атаковав нетипичное для казино устройство, хакеры нашли лазейку и таким образом обошли традиционные инструменты безопасности игорного заведения. Получив контроль над аквариумом, киберпреступники начали сканирование всей системы и обнаружили в ней другие уязвимости. О последствиях хакерской атаки ничего не сообщается. Но, судя по всему, казино не пострадало.

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

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

В отчете Darktrace рассказывается о еще 8 случаях необычных атак на учреждения из самых разных сфер. Но в числе тех, кого хакеры взламывают чаще всего, одну из лидерских позиций занимает сфера финансов. Нередко от действий киберпреступников страдают биржи и брокеры, о чем свидетельствуют недавние события в Малайзии.

Атака на малайзийских брокеров




Изображение: Rog b, CC BY-NC 2.0

Малайзийская комиссия по коммуникациям и мультимедиа (MCMC) изучает сообщения о кибератаках, нарушивших онлайн-трейдинг в ряде брокерских компаний. От действий хакеров пострадала Jupiter Securities Sdn Bhd. Незадолго до этого компания N2N Connect Bhd, которая предоставляет торговые решения для брокерских фирм, предупредила своих клиентов о возможной DDoS-атаке.

5 июля на дата-центры N2N Connect Bhd было совершено скоординированное нападение. На первый из них удар обрушился в промежутке с 8 до 10.30 утра, а чуть позже хакеры атаковали и второй. Известно также, что от действий киберпреступников пострадали и те брокерские дома, которые не сотрудничали с N2N Connect Bhd.

Пострадавшие брокеры ранее получали по электронной почте письма от хакеров-шантажистов. Последние требовали заплатить им, чтобы предотвратить нападение, которое может привести к краху их торговых систем. Малайзийское издание The Star приводит текст одного из таких писем: «Если выкуп не будет выплачен в течение отведенного времени, сумма будет увеличиваться, и компании столкнутся с крупномасштабными атаками».

О перебоях в работе своего дата-центра в результате DDoS-атак заявляла также Excel Force MSC Bhd. Нападение продлилось около часа, данные не пострадали и не были похищены. Тем не менее, компания ввела дополнительные профилактические меры.

Кроме того, один из местных брокеров, которого СМИ не называют, принял радикальные меры безопасности в связи с угрозой кибератак и временно заблокировал доступ к своей торговой системе для всех иностранцев.

Bursa Malaysia (Фондовая биржа Куала-Лумпур) заявила, что нападения хакеров не вызвали каких-либо сбоев в торгах, поскольку своевременно были приняты меры для обеспечения защиты инфраструктуры от любой кибератаки.

Для того, чтобы минимизировать возможный ущерб как от хакерских атак, так и технических сбоев, брокерские компании разрабатывают различные системы защиты клиентов. О том, как реализована подобная защита в торговой системе ITinvest MatriX можно прочитать по ссылке.

Другие материалы по теме финансов и фондового рынка от ITinvest:


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334396/


Метки:  

Наведение порядка: в Chrome и Firefox будет прекращено доверие к удостоверяющему центру Symantec

Суббота, 29 Июля 2017 г. 13:25 + в цитатник
unlockКак обычно, до ката нужно привести выжимку: в связи с проблемами в организации работы инфраструктуры, нарушениями при подготовке отчётности и злоупотреблениями, которые привели к выдаче сертификатов уровня EV (Extended Validation) без требуемых проверок, в настоящее время Goolge и Mozilla планируют процесс утраты доверия к сертификатам Symantec.

Компания Symantec согласилась с 1 декабря 2017 года ввести в строй новый процесс выдачи сертификатов, при котором компания не будет иметь своего корневого сертификата и будет выступать агентом другого удостоверяющего центра, выполняя роль SubCA (Subordinate Certificate Authority), работающего под внешним контролем (Managed CA). Сертификаты Symantec, выданные после 1 декабря 2017 года, не будут подпадать под блокировку и, судя по всему, продолжат работу.


В 2010 году Symantec за сумму в 1.28 млрд долларов приобрёл бизнес аутентификации у компании VeriSign, став, таким образом, одним из крупнейших удостоверяющих центров (с долей в 14% всех сертификатов в мире). Однако даже такие масштабы (и ожидаемые в связи с этим рост внимания к собственным инфраструктуре и процессам) не позволили компании вести бизнес полностью корректно, что привело, в конце концов, к множественным претензиям со стороны производителей браузеров.

В частности, очень острой оказалась ситуация с выдачей EV-сертификатов. Как известно, сертификаты уровня Extended Validation (EV) подтверждают заявленные параметры идентификации владельца, и, по правилам, для их получения требуется проведение проверки документов о принадлежности домена, а также физическое присутствие владельца ресурса. В случае Symantec подобная проверка не проводилась должным образом, т.е. нет гарантии, что полномочия владельца всегда проверялись. Весной 2017 года в Google обратили внимание на то, что Symantec предоставил доступ к инфраструктуре удостоверяющего центра как минимум четырём сторонним организациям, которым предоставлены полномочия по выдаче сертификатов. При этом компания Symantec не обеспечила должный уровень надзора за ними и допустила несоблюдение ими установленных стандартов обслуживания.

В ответ на запросы, компания Symantec также не могла предоставить в установленные сроки отчёты с разбором имевшихся инцидентов. В частности, исследователями безопасности было выявлено, что в январе 2017 удостоверяющим центром Symantec были сгенерированы 108 неправильно выданных сертификатов. Ранее, компания Symantec уже была вовлечена в скандал, связанный с выдачей сертификатов посторонним на чужие домены, в частности осенью 2015 года было уволено (ссылка на архивную копию страницы) несколько сотрудников, которые были уличены в выдаче тестовых сертификатов на домены (в том числе на домены google.com, gmail.com и gstatic.com), без получения согласия владельцев доменов — неудивительно, таким образом, что Google отнеслась к ситуации без лишней сердечности.

Для того, чтобы сгладить последствия прекращения доверия к сертификатам Symantec и предоставить пользователям время обновить свои сертификаты, разработчики Chrome пошли на компромисс и согласились провести процесс поэтапно, дав Symantec возможность перестроить свои организационные процессы, устранить проблемы в инфраструктуре и перейти на новые корневые сертификаты.

Первый этап прекращения доверия запланирован на выпуск Chrome 66, релиз которого ожидается 17 апреля 2018 года. На этом этапе будет утрачено доверие к сертификатам Symantec, выписанным до 1 июня 2016 года. Следует отметить, что в Mozilla обсуждается предложение по применению первого этапа блокировки, начиная с 1 декабря 2017 года, т.е. на четыре месяца раньше, но, скорее всего, окончательно будет утверждена дата близкая к апрелю 2018 года. Google также рассматривал возможность блокировки в октябрьском и декабрьском выпусках Chrome 62 и 63, но отложил блокировку до Chrome 66, приняв во внимание пожелания отрасли.

Полное прекращение поддержки сертификатов Symantec ожидается в Chrome 70 (запланирован на 23 октября 2018 года). Mozilla планирует полностью прекратить доверие к сертификатам Symantec в Firefox 63 (16 октября 2018) или 64 (27 ноября 2018). Для избежания проблем, сайтам, имеющим сертификаты Symantec, рекомендуется не затягивать с обновлением сертификата. Утрата доверия также затронет сертификаты удостоверяющих центров GeoTrust, Thawte и RapidSSL, которые были связаны цепочкой доверия с корневым сертификатом Symantec.

В дальнейшем Symantec сможет параллельно провести полную реструктуризацию своей инфраструктуры, устранив слабые места в текущей цепочке взаимодействия с подчинёнными организациями и партнёрами, которым делегированы права выдачи сертификатов. Symantec также не исключает возможность продажи подразделения, занимающегося выдачей сертификатов.

Вот так, компания, столько успешно умудрявшаяся продавать саму идею безопасности, уже не в первый раз оказывает в центре скандалов и проблем, связанных с предлагаемыми ею решениями.
Вы верили сертификатам от CA, принадлежащих Symantec?

Проголосовало 4 человека. Воздержалось 9 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334392/


Метки:  

Android Architecture Components в связке с Data Binding

Суббота, 29 Июля 2017 г. 12:58 + в цитатник


Не так давно для андроид-разработчиков Google представил новую библиотеку — Android Architecture Components. Она помогает реализовать в приложении архитектуру на основе паттернов MVx (MVP, MVVM etc.). Кроме того, уже давно выпущена другая библиотека от Google — Data Binding Library. Она позволяет прямо в разметке связывать отображение UI-контролов со значениями, содержащимися в объектах. Это важная особенность паттерна MVVM — связывать слой View со слоем ViewModel.


Обе библиотеки направлены на построение архитектуры Android-приложений в MVVM стиле.
Я расскажу, как можно использовать их вместе для создания проекта с архитектурой на основе MVVM.



Немного об MVVM


Паттерн MVVM предполагает разделение архитектуры приложения на 3 слоя:


  • Model — слой данных. Содержит всю бизнес-логику приложения, доступ к файловой системе, базе данных, ресурсам системы и другим внешним сервисам;
  • View — слой отображения. Все, что видит пользователь и с чем может взаимодействовать. Этот слой отображает то, что представлено в слое ViewModel. Также он отправляет команды (например, действия пользователя) на выполнение в слой ViewModel;
  • ViewModel — слой представления. Связан со слоем View байндингами. Содержит данные, которые отображены на слое View. Связан со слоем Model и получает оттуда данные для отображения. Также обрабатывает команды, поступающие из слоя View, изменяя тем самым слой Model.

MVVM
Основной интерес в статье будет прикован к байндингам. Это связи отображения конкретных параметров View (например, “text” у TextView) с конкретными полями представления ViewModel (например, поле “имя пользователя”). Задаются они в разметке View (в layout), а не в коде. ViewModel, в свою очередь, должна так представлять данные, чтобы их было легко связать байндингами с View.


Зачем нам это все надо?


Сам по себе паттерн MVVM, как и MVP, и MVC, позволяет разделить код на независимые слои. Основное отличие MVVM — в байндингах. То есть, в возможности прямо в разметке связать отображение того, что видно пользователю — слой View, с состоянием приложения — слоем Model. В общем, польза MVVM в том, чтобы не писать лишний код для связывания представления с отображением — за вас это делают байндинги.


Google двигается в сторону поддержки архитектуры на основе паттерна MVVM. Библиотеки Android Architecture Components (далее, AAC) и Data Binding — прямое тому подтверждение. В будущем, скорее всего, этот паттерн будет использоваться на большинстве проектах под Android.


На данный момент проблема в том, что ни AAC, ни Data Binding не предоставляет возможности реализовать MVVM паттерн в полной мере. AAC реализует слой ViewModel, но байндинги надо настраивать вручную в коде. Data Binding, в свою очередь, предоставляет возможность написать байндинги в разметке и привязать их к коду, но слой ViewModel надо реализовывать вручную, чтобы прокидывать обновление состояния приложения через байндинги к View.


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


В общем, что надо для этого сделать:


  • реализовать слой View на байндингах;
  • реализовать слой ViewModel на основе классов LiveData и ViewModel из AAC;
  • связать эти два слоя минимальным количеством кода;
  • оформить это так, чтобы это можно было переиспользовать в проектах.

Сделать это попробуем на примере простого экрана профиля пользователя.


Описание примера


На экране будет три элемента:


  • кнопка войти/выйти. Текст зависит от того, авторизован пользователь или нет;
  • поле ввода логина. Показывается, когда пользователь не авторизован;
  • лэйбл с логином. Показывает логин авторизованного пользователя.

Логин будет храниться в SharedPreferences. Пользователь считается авторизованным, если в SharedPreferences записан какой-нибудь логин.


Для простоты не будут использоваться сторонние фреймворки, запросы к сети, а также отображение ошибок.


Слой View


Начну я со слоя View, чтобы было понятно, что будет видно пользователю на экране. Сразу же размечу нужные мне байндинги без привязки к конкретной ViewModel. Как это все будет работать — станет понятно позже.


Собственно, layout:



    
        
        
        
        
    

    

        
        

        
        

        
        

    

Класс LiveData


Перед реализацией слоя Model надо разобраться с классом LiveData из AAC. Он нам понадобится для нотификации слоя ViewModel об изменениях слоя Model.


LiveData — это класс, объекты которого поставляют данные и их обновления подписчикам. Он представляет собой реализацию паттерна Observer. На LiveData можно подписаться, а сама LiveData реализует внутри то, как она будет вычислять и обновлять данные для подписчиков.


Особенность LiveData в том, что она может быть привязана к объекту жизненного цикла и активироваться, только когда такой объект в состоянии started. Это удобно для обновления слоя View: пока активити или фрагмент в состоянии started, это значит, что у них инициализирован весь UI и им нужны актуальные данные. LiveData реагирует на это и активизируется — рассчитывает актуальное значение и уведомляет подписчиков об обновлении данных.


Слой Model


От слоя Model нам нужна следующая функциональность: методы login(String login), logout() и возможность отслеживать текущий логин авторизованного пользователя на основе LiveData.


Добавим класс ProfileRepository, который будет отвечать за логику авторизации пользователя:


class ProfileRepository(context: Context) {
    private val loginKey = "login"
    private val preferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
    // LiveData, на которую можно подписаться
    // и получать обновления логина пользователя
    private val innerLoggedInUser = LoggedInUserLiveData()

    val loggedInUser: LiveData
        get() = innerLoggedInUser

    fun login(login: String) {
        preferences.edit().putString(loginKey, login).apply()
        notifyAboutUpdate(login)
    }

    fun logout() {
        preferences.edit().putString(loginKey, null).apply()
        notifyAboutUpdate(null)
    }

    private fun notifyAboutUpdate(login: String?) {
        innerLoggedInUser.update(login)
    }

    private inner class LoggedInUserLiveData : LiveData() {
        // так лучше не делать в конструкторе, а высчитывать текущее значение асинхронно
        // при первом вызове метода onActive. Но для примера сойдет
        init { value = preferences.getString(loginKey, null) }

        // postValue запрашивает обновление на UI-потоке
        // используем, так как мы не уверены, с какого потока будет обновлен логин
        // для немедленного обновления на UI-потоке можно использовать метод setValue
        fun update(login: String?) {
            postValue(login)
        }
    }
}

Этот объект разместим в Application, чтобы было проще получить к нему доступ, имея Context:


class AacPlusDbTestApp : Application() {

    lateinit var profileRepository: ProfileRepository
        private set

    override fun onCreate() {
        super.onCreate()
        profileRepository = ProfileRepository(this)
    }
}

Класс ViewModel


Перед реализацией слоя ViewModel надо разобраться с основным классом из AAC, использующимся для этого.


ViewModel — это класс, представляющий объекты слоя ViewModel. Объект такого типа может быть создан из любой точки приложения. В этом классе всегда должен быть либо дефолтный конструктор (класс ViewModel), либо конструктор с параметром типа Application (класс AndroidViewModel).


Чтобы запросить ViewModel по типу, нужно вызвать:


    mvm = ViewModelProviders.of(fragmentOrActivity).get(MyViewModel::class.java)

Либо по ключу:


    mvm1 = ViewModelProviders.of(fragmentOrActivity).get("keyVM1", MyViewModel::class.java)
    mvm2 = ViewModelProviders.of(fragmentOrActivity).get("keyVM2", MyViewModel::class.java)

ViewModel хранятся отдельно для каждой активити и для каждого фрагмента. При первом запросе они создаются и помещаются для хранения в активити или фрагменте. При повторном запросе — возвращается уже созданная ViewModel. Уникальность конкретной ViewModel — это ее тип или строковый ключ + где она хранится.


Создаются ViewModel и AndroidViewModel по умолчанию через рефлексию — вызывается соответствующий конструктор. Так что, при добавлении своих конструкторов, в методе ViewModelProviders.of(...) нужно явно указывать фабрику создания таких объектов.


Слой ViewModel


От ProfileViewModel нам надо следующее:


  • метод loginOrLogout, который будет представлять команду логина или логаута пользователя, в зависимости от того, авторизован ли пользователь;
  • изменяемое значение isUserLoggedIn, которое будет представлять состояние — авторизован ли пользователь;
  • изменяемое значение loggedInUser, которое будет представлять логин текущего авторизованного пользователя;
  • изменяемое значение inputLogin, которое будет представлять то, что пользователь ввел на экране в поле логина.

Создадим ProfileViewModel и свяжем ее с ProfileRepository:


// наследуем от AndroidViewModel, для доступа к ProfileRepository через Application
class ProfileViewModel(application: Application) : AndroidViewModel(application) {
    private val profileRepository: ProfileRepository = (application as AacPlusDbTestApp).profileRepository
    // класс Transformations — это класс-хэлпер для преобразования данных
    // метод map, просто конвертирует данные из одного типа в другой - в данном случае из String? в boolean
    val isUserLoggedInLiveData = Transformations.map(profileRepository.loggedInUser) { login -> login != null }
    // LiveData чтобы отслеживать логин авторизованного пользователя
    val loggedInUserLiveData = profileRepository.loggedInUser
    // представляет логин, введенный пользователем с клавиатуры
    // TextField - это ObservableField, реализующий интерфейс TextWatcher
    //    это нужно, чтобы можно было байндиться к text и addTextChangedListener,
    //    организовав таким образом двустронний байндинг.
    // При вводе текста в EditText изменяется ViewModel, при изменении ViewModel — изменяется  EditText.
    val inputLogin = TextField()

    fun loginOrLogout() {
        // необходимо получить текущее состояние - авторизован пользователь или нет и решить, что делать
        isUserLoggedInLiveData.observeForever(object : Observer {
            override fun onChanged(loggedIn: Boolean?) {
                if (loggedIn!!) {
                    profileRepository.logout()
                } else if (inputLogin.get() != null) {
                    // вызываем логин только если пользователь что-то ввел в поле ввода
                    profileRepository.login(inputLogin.get())
                } else {
                    // по идее, тут можно отобразить ошибку "Введите логин"
                }
                // при выполнении команды приходится отписываться вручную
                isUserLoggedInLiveData.removeObserver(this)
            }
        })
    }
}

Теперь при вызове метода loginOrLogout в ProfileRepository будет обновляться LoginLiveData и эти обновления можно будет отображать на слое View, подписавшись на LiveData из ProfileViewModel.


Но LiveData и ViewModel пока что не адаптированы под байндинг, так что использовать этот код еще нельзя.


Адаптация ViewModel под Data Binding


С доступом к ViewModel из разметки проблем особых нет. Объявляем ее в разметке:



   
        
   
   ...

И устанавливаем в активити или фрагменте:


// наследуем от LifecycleActivity, так как это может понадобиться для LiveData.
// LiveData будет активироваться, когда эта активити будет в состоянии started.
class ProfileActivity : LifecycleActivity() {

    lateinit private var binding: ActivityProfileBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // инициализируем байндинг
        binding = DataBindingUtil.setContentView(this, R.layout.activity_profile)
        // устанавливаем ViewModel для байндинга
        binding.profileViewModel = ViewModelProviders.of(this).get(ProfileViewModel::class.java)
    }
}

Адаптация LiveData под Data Binding


Адаптировать LiveData я решил на основе класса ObservableField. Он позволяет привязать изменяющееся значение произвольного типа к конкретному свойству view.


В моем примере надо будет прибайндить visibility у view к тому, авторизован пользователь или нет. А также свойство text к логину пользователя.


У ObservableField есть два метода — addOnPropertyChangedCallback и removeOnPropertyChangedCallback. Эти методы вызываются, когда добавляется и удаляется байндинг из view.
По сути, эти методы — те моменты, когда нужно подписываться и отписываться от LiveData:


// наследуем от ObservableField
// имплементируем Observer (подписчик для LiveData) чтобы синхронизировать значения LiveData и ObservableField
class LiveDataField(val source: LiveData) : ObservableField(), Observer {
    // отслеживаем количество подписчиков на этот ObservableField
    private var observersCount: AtomicInteger = AtomicInteger(0)

    override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
        super.addOnPropertyChangedCallback(callback)
        if (observersCount.incrementAndGet() == 1) {
            // подписываемся на LiveData, когда к ObservableField прибайндивается первая view
            source.observeForever(this)
        }
    }

    override fun onChanged(value: T?) = set(value)

    override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
        super.removeOnPropertyChangedCallback(callback)
        if (observersCount.decrementAndGet() == 0) {
            // отписываемся от LiveData, когда все view отбайндились от ObservableField
            source.removeObserver(this)
        }
    }
}

Для подписки на LiveData я использовал метод observeForever. Он не передает объект жизненного цикла и активирует LiveData независимо от того, в каком состоянии находятся активити или фрагмент, на котором находятся view.


В принципе, из объекта OnPropertyChangedCallback можно достать view, из view — context, context привести к LifecycleActivity и привязать LiveData к этой активити. Тогда можно будет использовать метод observe(lifecycleObject, observer). Тогда LiveData будет активироваться только когда активити, на которой находится view, в состоянии started.


Выглядеть этот хак будет примерно так:


class LifecycleLiveDataField(val source: LiveData) : ObservableField(), Observer {
...
    override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
        super.addOnPropertyChangedCallback(callback)
        try {
            // немножко рефлексии, по-другому никак
            val callbackListenerField = callback.javaClass.getDeclaredField("mListener")
            callbackListenerField.setAccessible(true)
            val callbackListener = callbackListenerField.get(callback) as WeakReference
            val activity = callbackListener.get()!!.root!!.context as LifecycleActivity
            if (observersCount.incrementAndGet() == 1) {
                source.observe(activity, this)
            }
        } catch (bindingThrowable: Throwable) {
            Log.e("BINDING", bindingThrowable.message)
        }
    }
...
}

Теперь изменим ProfileViewModel так, чтобы к ней можно было легко прибайндиться:


class ProfileViewModel(application: Application) : AndroidViewModel(application) {
...
   // представляет логин авторизованного пользователя или null
   val userLogin = LifecycleLiveDataField(loggedInUserLiveData)
   // представляет авторизован ли пользователь
   val isUserLoggedIn = LifecycleLiveDataField(isUserLoggedInLiveData)
...
}

Важно! В процессе тестирования обнаружился один неприятный недостаток в библиотеке Data Binding — прибайнденные view не вызывают метод removeOnPropertyChangedCallback даже когда активити умирает. Это приводит к тому, что слой Model держит ссылки на объекты слоя View через слой ViewModel. В общем, утечка памяти из объектов LiveDataField.


Чтобы этого избежать, можно использовать еще один хак и вручную обнулить все байндинги на onDestroy активити:


class ProfileActivity : LifecycleActivity() {
...
    override fun onDestroy() {
        super.onDestroy()
        // обнуляем поле profileViewModel
        binding.profileViewModel = null
        // необходимо вручную вызвать обновление байндингов,
        // так как автоматическое обновление не работает на этапе onDestroy :(
        binding.executePendingBindings()
    }
}

Кроме того, внимательные читатели могли заметить в разметке класс SafeEditText. В общем, он понадобился, из-за бага в Data Binding Library. Суть в том, что она добавляет в листенер вводимого текста через addTextChangedListener даже если этот листенер null.
Так как на этапе onDestroy я обнуляю модель, то сперва в EditText добавляется null-листенер, а потом обновляется текст, который стал тоже null. В итоге на onDestroy происходил NPE краш при попытке оповестить null-листенер о том, что текст стал null.


В общем, при использовании Data Binding будьте готовы к таким багам — их там довольно много.


Не идеально, но получилось


В общем, с некоторыми трудностями, хаками и некоторыми разочарованиями, но связать AAC и Data Binding получилось. Скорее всего, в скором времени (года 2?) Google добавит какие-нибудь фичи, чтобы связать их — тот же аналог моей LiveDataField. Пока что AAC в альфе, так что там многое еще может измениться.


Основные проблемы на текущий момент, на мой взгляд, связаны с библиотекой Data Binding — она не подстроена под работу с ViewModel и в ней есть неприятные баги. Это наглядно видно из хаков, которые пришлось использовать в статье.


Во-первых, при байндинге сложно получить активити или фрагмент, чтобы получить LifecycleObject, необходимый для LiveData. Эту проблему можно решить: либо достаем это через рефлексию, либо просто делаем observeForever, который будет держать подписку на LiveData, пока мы вручную не обнулим байндинги на onDestroy.


Во-вторых, Data Binding предполагает, что ObservableField и прочие Observable объекты живут тем же жизненным циклом, что и view. По факты эти объекты — это часть слоя ViewModel, у которой другой жизненный цикл. Например, в AAC этот слой переживает перевороты активити, а Data Binding, не обновляет байндинги после переворота активити — для нее все view умерли, а значит, и все Observable объекты тоже умерли и обновлять ничего нет смысла. Эту проблему можно решить обнулением байндингов вручную на onDestroy. Но это требует лишнего кода и необходимости следить, что все байндинги обнулены.


В-третьих, возникает проблема с объектами слоя View без явного жизненного цикла, например, ViewHolder адаптера для RecyclerView. У них нет четкого вызова onDestroy, так как они переиспользуются. В какой момент обнулять байндинги во ViewHolder — сложно сказать однозначно.


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


Пример из статьи можно посмотреть на гитхабе Touch Instinct.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330830/


[Перевод] Искусственная глупость: искусство намеренных ошибок

Суббота, 29 Июля 2017 г. 11:21 + в цитатник
image

Всё должно быть изложено так просто, как только возможно, но не проще.
— Альберт Эйнштейн

Чтобы игра была развлекающей и интересной, не обязательно делать управляемых компьютером противников умнее. В конце концов, игрок должен побеждать. Однако позволять ему выигрывать только потому, что управляющий противниками ИИ разработан плохо, тоже неприемлемо. Интерес к игре можно увеличить, если совершаемые противником ошибки будут намеренными. Тщательно настроив ошибки противников, сделав их намеренными, но правдоподобными, программисты позволят противникам выглядеть умными и одновременно обеспечат победу игрока. Кроме того, отслеживая системы ИИ и соответствующим образом управляя ими, можно превратить ситуации, в которых противники выглядят глупо, в интересный игровой процесс.

Частая ошибка в разработке и реализации систем ИИ в компьютерных играх заключается в слишком сложном дизайне. Разработчику ИИ легко увлечься созданием умного игрового персонажа и потерять из виду конечную цель, а именно создание развлекающей игры. Если у игрока есть иллюзия того, что компьютерный противник делает что-то умное, то неважно, каким образом ИИ (если он есть) создаёт эту иллюзию. Признак хорошего программиста ИИ — способность противостоять искушению добавить интеллекта туда, где он не нужен, и распознавание ситуаций, в которых достаточно более «дешёвых» и простых решений. Программирование ИИ часто больше похоже на искусство, чем на науку. Способность различать моменты, в которых достаточно дешёвых трюков, и тех, где требуется более сложний ИИ, даётся непросто. Например, программист, обладая полным доступом ко всем структурам игровых данных, легко может читерить, сделав NPC всезнающими. NPC могут знать, где находятся враги, где лежит оружие или амуниция, не видя их. Однако, игроки часто распознают такие дешёвые трюки. Даже если они не могут определить саму природу читерства, у них может создаться ощущение, что поведение NPC не похоже на естественное.

Несколько трюков


Довольно просто создать NPC, способного победить живого игрока. Гораздо сложнее создать такого, который может проиграть игроку в напряжённом бою. Трудность заключается в том, чтобы продемонстрировать игроку навыки NPC, но в то же время дать игроку победить. Ниже приведено несколько трюков, позволяющих игре показать интеллект NPC и обеспечить интересный игровой процесс. Эти трюки в основном рассчитаны на шутеры от первого лица (FPS), но некоторые применимы и в других жанрах.

Сначала движение, потом стрельба


Ничто не раздражает больше, чем мгновенная смерть от руки компьютерного противника сразу после попадания в новую комнату или область. Игрок, попадая в новое место, скорее всего будет перегружен впечатлениями от новых текстур, новых объектов, новой геометрии. Задача распознавания среди фоновых текстур уникальных текстур врага — не очень большое удовольстве. Это особенно верно сейчас, когда бюджеты на создание полигональных моделей и текстур значительно выросли. Все атаки NPC, происходящие в такие моменты, очень огорчают. Нужно всеми силами стремиться избегать таких приёмов. В таких ситуациях игрок не знает о грядущих опасностях и никаким способом не может понять, откуда в него стреляют.

image

Простейший способ снизить раздражение игрока: когда враг видит игрока, он должен начать двигаться, а не стрелять в него. Заставьте NPC перед атакой убежать с уязвимой открытой позиции в укрытие, чтобы предупредить игрока о начинающемся бое. В ситуации с несколькими противниками достаточно движения только одного из них, в то время как другие NPC могут просто ждать, прежде чем нападать на игрока.

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

Будьте заметны


Хотя в реальном бою противники стремятся быть как можно более невидимыми, в игровом мире отличный камуфляж создаёт плохой геймплей. Разглядывание пикселей в поисках противников — не слишком интересный процесс. Сделайте текстуры NPC контрастными относительно фона, чтобы игрок быстрее обнаруживал врагов и переходил к настоящему процессу игры. На униформе противников могут быть похожие на камуфляж узоры, но их цвет и яркость должны сильно контрастировать с окружением.

Не будьте снайпером


Активные перестрелки — это хорошо, они заставляют игрока двигаться и создаёт напряжение, повышая таким образом темп игры. Но они неприятны, когда игрок умирает слишком быстро. Простейший способ сделать NPC глупее и ускорить темп игры — дать компьютерным противникам сбитые прицелы. Благодаря этому можно использовать активные перестрелки, не делая игру слишком сложной для игрока. В FPS часто используется разброс пуль вплоть до 40 градусов.

Или же можно снизить сложность игры, уменьшив ущерб от пуль противника. Однако при этом теряются некоторые дополнительные преимущества плохого прицеливания. Одно из случайных последствий плохого прицеливания — это напряжение, возникающее при пролетании трассирующих пуль над головой игрока, облака бетонной пыли или искры от пуль, ударяющихся об стену рядом с игроком. Кроме того, промах награждает игрока: игроки часто считают близкие промахи подтверждением правильности выбранной тактики передвижения.

image

Промахнитесь с первый раз


Для оружия, наносящего большой урон (например, убивающего с одного-двух попаданий), требуется нечто большее. Обычно игроку не очень интересно внезапно и неожиданно получать большой урон. В таких ситуациях игроки часто чувствуют себя обманутыми. Можно снизить раздражаение, намеренно промахнувшись по игроку в первый раз. Это даёт игроку секунду, чтобы отреагировать, и сохраняет высокий уровень напряжений.

Кроме того, намеренные первые промахи можно располагать стратегически. Один из самых раздражающих аспектов выстрелов игроку в спину заключается в том, что игрок не понимает, откуда в него стреляли. В некоторых FPS пытались уменьшить эту проблему добавлением подсказок на экране (например, мерцающих красных значков), показывающих направление атаки. Такие подсказки (обычно воспринимаемые как часть интерфейса пользователя), разрушают иллюзию реальности и на удивление не так очевидны для игрока, как можно было ожидать.

Намеренные промахи, в особенности при выстрелах сзади, могут уменьшить эту проблему, указывая направление атаки, при этом не разрушая иллюзию реальности. Лазерный луч или трассирующая пуля, стратегически попадающая в пол или стену прямо перед убегающим игроком, показывает направление, с которого происходит нападение. К тому же информация о направлении, передаваемая лазерными лучами или трассерами, намного информативнее, чем простые мерцающие экранные подсказки. Они позволяют игроку более правильно реагировать на атаку.

Ещё один ценный способ использования намеренных промахов — попадание в определённые объекты окружения. Например, когда игрок приближается к бочке с водой, фарфоровой статуе или стеклянной вазе, противнику вместо выстрела в игрока лучше прицелиться в ближайший к тому разрушаемый объект, лучше всего тот, который разваливается наиболее драматично. Не забывайте — цель программиста хорошего ИИ — не убить игрока, а создать напряжение.

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

Предупреждайте игрока


Ещё один эффективный способ повышения удовольствия от игры — предупреждение игрока перед атакой. Её можно реализовать визуально, воспроизводя короткую анимацию подготовки к нападению, или аудиально, проигрыванием звука (писка, щелчка и т.д.) или криком «Попался!» или «Получай!». Звуковые подсказки особенно важны, когда на игрока нападают сзади. Они дают игроку шанс отреагировать на атаку, чтобы он не чувствовал себя обманутым.

Поскольку люди в реальном бою никогда не останавливаются, чтобы предупредить своих врагов, то можно подумать, что из-за этого компьютерные противники будут выглядеть глупее. Напротив, такие предупреждения можно использовать для привлечения внимания к другим, более примечательным аспектам ИИ. Например, умного NPC можно запрограммировать на поиск маршрутов обходов врага с фланга или нахождения мест для засады [Lid'en02]. Если игроки после попадания в засаду сразу же гибнут, то они не смогут оценить все изощрённые тактики противника. Интеллектуальное поведение будет более заметно, если NPC издаёт предупредительный звук, чтобы у игрока осталось время повернуться и увидеть затаившегося в умно подобранном для засады месте NPC. Если NPC в засаде постоянно убивает игрока, игра больше не будет доставлять удовольствия. Предупреждая игроков, вы даёте им время увидеть ум ИИ и отреагировать на его поведение, не умерев.

Ещё одно преимущество звуковых подсказок заключается в том, что игрок быстро учится реагировать на определённые звуки, если они неизменны [Madhyastha95]. Например, если конкретная фраза («Попался!») предшествует атаке, после нескольких таких случаев звук будет вызывать у игрока физическую реакцию. Такое условное поведение может значительно увеличить напряжённость игры. Более того, если фраза «Попался!» используется только когда враг применяет определённую боевую стратегию ИИ (например, разбирается, как обойти игрока с фланга), то увидев несколько раз сочетание флангового маневра и крика «Попался!», в дальнейшем игрок будет ожидать сложного обхода с фланга, даже если не видит его.

Нападайте в стиле «кунг-фу»


Во многих играх игрок находится в роли «Рэмбо» (другими словами, в одиночку противостоит целой армии). Хотя во многих жанрах выкашивание толп врагов одной очередью вполне приемлемо, противники в таких играх похожи на беззащитных ягнят с очень слабым искусственным интеллектом. Однако если наши противники умны, то схватка с несколькими из них одновременно оказывается слишком сложной для игрока. С другой стороны, большее количество врагов создаёт интересный и динамичный игровой процесс.

Решение заключается в дизайне боёв в стиле «кунг-фу». Другими словами, даже если одновременно рядом с игроком несколько NPC, нападает на него только пара. Другие занимаются перезарядкой оружия, прячутся или меняют позицию. Ни один из противников не должен оставаться на одном месте слишком долго, даже если текущее положение обеспечивает хорошую позицию для атаки. Меняясь ролями в атаке и постоянно двигаясь, противники создают активную боевую ситуацию, в которой игроку противостоит множество врагов, но атакуют его только некоторые. Удивительно, но игроки, встретившиеся с такой ситуацией, обычно не осознают, что их одновременно активно атакуют не более двух противников, даже если сражение идёт с большой группой врагов.

Сообщите игроку, что вы делаете


Когда игрок видит действия NPC, ему иногда сложно их интерпретировать. Будет ли бегущий противник прятаться, звать подкрепление, обходить с фланга или просто бежать без всякой цели, стараясь не нарваться на пулю? Сложное поведение NPC часто ускользает от игрока. Когда такое происходит, вся работа разработчика ИИ идёт прахом. Эффективный способ справиться с этой сложность — в буквальном смысле говорить игроку о том, что делает ИИ. Например, при выполнении действия противник может крикнуть своим соратникам «Обхожу с фланга!», «Прикрой!», или «Отступаю!». Такие подсказки могут иметь очень высокую эффективность и часто дают побочный эффект: игроки предполагают наличие интеллекта там, где его нет.

Реагируйте на ошибки


Даже самые изощрённые системы ИИ ошибаются, это неизбежно. Если подойти к ошибкам неправильно, то NPC будут казаться тупыми. Распознав возникновение ошибки и с умом отреагировав на неё, вы не только сохраните иллюзию интеллекта, но и превратите ошибки в особенности.

Рассмотрим вычисления, необходимые для точного поражения цели. В богатом 3D-мире с движущимися объектами (в том числе с другими NPC и игроком), несмотря на все сложные физические расчёты неизбежно возникают ошибки. Граната отскакивает от объекта или другого NPC и падает к ногам бросившего её NPC. (Не забывайте, что игроки тоже иногда делают эту ошибку!)

Если мы просто позволим NPC стоять и ждать взрыва, то ИИ покажется довольно жалким. Однако если мы распознаем ошибку, то сможем соответствующим образом отреагировать на неё. Если бросивший гранату NPC прикрывает голову, демонстрирует удивление и/или страх, кричит «Не-е-ет!», то это больше не выглядит ошибкой ИИ. Теперь ошибка превратилась в особенность, она добавляет NPC индивидуальности, а в игре появляется немного юмора и интересной вариативности.

image

Отступайте в последний момент


Задача системы ИИ — создание для игрока интересного и напряжённого игрового процесса. В идеале у игрока должно быть ощущение сложности, загнанности в угол, но в результате он всё равно должен победить. Один из способов реализации — встроить «подталкивание к краю» в саму архитекруту ИИ. В этой модели NPC активно атакуют игрока почти до самой смерти. Показатели игрока тщательно отслеживаются, чтобы его здоровье или ресурсы почти полностью истощались, но не до конца. Когда игрок достигнет предела, ИИ отступает, нападает менее эффективно, и его становится проще убить. После победы такая ситуация воспринимается игроком как настоящий подвиг. Однако при таком подходе разработчик должен быть очень аккуратным, чтобы игроки не поняли, что ими таким образом манипулируют. Если этот трюк можно распознать, он однозначно разрушает ощущения от игрового процесса.

Намеренные уязвимости


Игроки учатся делать упор на слабостях противника, даже если они возникают непреднамеренно. Поэтому вместо того, чтобы позволять игроку находить такие уязвимости, часто лучше встроить их в поведение NPC. Например, бегущему NPC может понадобиться остановиться и подготовить оружие, то есть у него уходит больше времени на атаку, чем у неподвижного. Противник, на которого напали сзади, может оказаться застигнутым врасплох и медленнее реагировать. Добавление несовершенства в поведение NPC тоже может сделать их более реалистичными и придать им индивидуальности. Например, при перезарядке NPC иногда может возиться дольше. Враг, знающий о том, как избегать мин-ловушек, может случайно нарваться на одну из них. Запланированные уязвимости делают управляемых компьютером персонажей более реалистичными. Непреднамеренные ошибки разрушают реализм. Для правильного подбора баланса требуется тщательное тестирование игрового процесса (плейтестинг).

Плейтестинг


Самый важный инструмент программиста ИИ — плейтестинг. Даже для разработчика с многолетним опытом создания ИИ тестирование игрового процесса — это единственный надёжный способ определить, когда можно использовать «дешёвые» решения, а когда стоит применить более сложные техники искусственного интеллекта. Не стоит недооценивать важность реакций неопытных тестеров на ИИ. Даже опытных разработчиков ИИ часто удивляют результаты плейтестинга и интерпретации, придумываемые игроками.

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

Любые знания о техниках и трюках разработки искусственного интеллекта могут повлиять на интерпретацию событий плейтестером. Во-вторых, плейтестеров должно быть много. Тому есть две причины. Первая: после внесения изменений в ИИ требуется новый набор игроков-новичков. Повторно используемые плейтестеры подвержены предубеждениям, внушённым предыдущей версией ИИ. Их интерпретация поведений NPC и техники игры будут отличаться от восприятия новичков. Вторая: поскольку навыки игроков бывают очень разными, необходимо большое количество плейтестеров. Возможно, единственный из тридцати тестер сможет найти критическую слабость ИИ, из-за которой NPC выглядят глупо или их легко убить. При тестировании малым коллективом игроков ИИ может выглядеть безупречным, но оказаться провальным после выхода игры на большой рынок.

Плейтестинг необходимо проводить на протяжении всего процесса разработки, а не только в конце производства. Распознавание факторов, влияющих на интересность и напряжённость — это сложный и длительный процесс. Планируйте, что вам придётся несколько раз отбрасывать идеи и начинать с нуля. Кроме того, важно позволить некоторым из плейтестеров тестировать игру во время всего процесса разработки. Игроки лучше осваиваются в игре и с большей вероятностью смогут найти лазейки в реализации ИИ. Кроме того, после долгой игры они научатся распознавать трюки ИИ.

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

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

Несколько примеров


Стандартная ошибка разработчиков ИИ — переусложнение дизайна. Часто достаточно гораздо более простого решения и дешёвые, но изобретательные решения оказываются значительно лучше. Например, программисты часто переусложняют дизайн при разработке тактики отрядов. Сложный обмен информацией и взаимодействия между бойцами часто не замечаются игроком, а потому необязательны. В игре Half-Life компании Valve [Valve98] есть впечатляющий пример того, как простые поведения могут создавать богатый геймплей, заставляющий игрока предполагать интеллектуальное поведение.

Десантники в Half-Life используют стиль боя «кунг-фу»: вне зависимости от количества десантников, с которыми сражается игрок, на самом деле одновременно в него разрешено стрелять максимум двоим. Между десантниками на самом деле не происходит никакого общения. Вместо этого каждому отряду бойцов даётся по два слота атаки. Если десантник хочет атаковать, но оба слота заполнены, то он находит себе другое занятие (например, перезарядку оружия или перемещение к новой позиции для атаки). Когда у одного из атакующих десантников заканчиваются патроны, он освобождает слот атаки и переключается на поведение поиска и перезарядки. Затем один из неатакующих десантников обнаруживает пустой слот, занимает его и начинает стрелять в игрока.

image

Добавлено ещё одно простое правило: когда слот атаки освобождается, и в бою есть несколько десантников, то освобождающий слот атаки боец кричит «Прикрой меня!». Хотя никакой коммуникации между этими десантниками не происходит, игрок воспринимает это так: один из бойцов просит прикрыть его, а второй открывает прикрывающий огонь. В реальности слот атаки освобождается и занимается другим десантником, ничего не знающем о перезарядке первого.

Во время плейтестинга обнаружилось, что когда игрок бросает гранату в группу NPC, алгоритм поиска пути Half-Life не способен найти путь побега для всех NPC. Поведение оставшихся NPC выглядело чрезвычайно тупым, они метались вокруг, пытаясь найти выход. Вместо переделки системы поиска путей (сложная задача), Valve решила обнаруживать возникшую проблему и воспроизводить специальную анимацию попавших в ловушку десантников — они приседали и закрывали головы руками. Такое поведение очень хорошо восприняли плейтестеры, потому что оно добавляло игре характерности.

Заключение


В этой статье рассмотрены важные концепции. Усилия разработчиков в области искусственного интеллекта так часто сосредоточены на том, чтобы сделать компьютерных противников умными, что они пренебрегают адекватным восприятием того, как ИИ делает игру интересной. Задача сложного ИИ — не убить игрока, а добавить напряжённости, управлять темпом игры и придать компьютерным персонажам индивидуальности. Простые решения часто лучше и интереснее, чем сложный искусственный интеллект. Добавляя в поведение NPC намеренные уязвимости, мы заставляем игрока обратить внимание на запланированные слабости ИИ, а не искать непреднамеренные. В этой статье также описаны различные трюки для того, чтобы системы ИИ максимизировали фактор развлекательности. Кроме того, не стоит считать, что годы разработки систем ИИ могут заменить тщательное тестирование игрового процесса.

Ссылки


[Lid'en02] Lid'en, Lars, «Strategic and Tactical Reasoning with Waypoints», AI Game Programming Wisdom, Charles River Media, 2002.
[Madhyastha95] Madhyastha, Tara and Reed, Daniel, «Data Sonification: Do You See What I Hear?» IEEE Software, Vol. 12, No. 2, 1995.
[Valve98] Valve LLC, “Half-Life,” 1998. См. www.valvesoftware.com
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334300/


Метки:  

[Из песочницы] Сравнение* древовидных графов

Суббота, 29 Июля 2017 г. 10:40 + в цитатник
Привет, Хабр!

* На самом деле не совсем так. При разработке информационной системы, частью которой является различная обработка конструкторско-технологической документации, у меня возникла проблема, которую вкратце можно описать следующим образом. Сегодня мы имеем один состав изделия, за день приходит несколько изменений по различным частям этого изделия и к вечеру уже неясно, что же изменилось? Изделия порой могут иметь более 10 000 элементов в составе, элементы не уникальны, а реальность такова, что изменения по составу могут активно приходить, хотя изделие уже почти готово. Непонимание объема изменений усложняет планирование.

Состав изделия можно представить в виде древовидного графа. Не найдя подходящего способа сравнения двух графов, я решил написать свой велосипед.

Задача


В течение дня различные изменения из конструкторской системы приходят в систему учета. На данных из системы учета строится планирование производства. Условия позволяют принять все изменения за день и пересчитать спецификацию изделия ночью. Но, как я писал выше, непонятно, чем отличается вчерашнее состояние от состояния сегодняшнего.

Хочется видеть что ушло из дерева изделия, а что добавилось. Так же хочется видеть какая деталь или сборка заменила другую деталь или сборку. Например, если в ветке дерева добавился промежуточный узел, то в таком случае неправильно будет считать, что все нижестоящие элементы удалились со старых мест и вставились на новые места. Они остались на своих местах, но произошла вставка промежуточного узла. Кроме того, элемент может «путешествовать» вверх и вниз только внутри одной ветки дерева, это обусловлено спецификой техпроцесса изготовления.



Подготовка


Спецификация изделия пересчитывается PL/SQL-процедурой внутри Oracle. Поэтому я счел логичным сделать и свой поиск изменений на PL/SQL.

Таблица, в которой хранится дерево изделия, назовем ее MR_ORDER_TREE, имеет следующий вид:
order_id ID заказа, на котором закреплено дерево
item_id ID элемента в дереве, вместе с order_id формирует первичный ключ и уникален в рамках заказа
item_ref ID элемента в который входит выбранный элемент
kts_item_id ID из справочника деталей и узлов
item_qty Количество
is_item_buy Покупное ли изделие
item_position Номер позиции в сборке

Связки (item_ref, kts_item_id) уникальны. Кроме покупки, позиции и количества имеются и другие атрибуты конкретного элемента, но речь не о них.

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

Итог сравнения будет храниться в таблице MR_ORDER_TREE_COMP, которая дополнительно будет иметь два столбца:
stat Столбец для отметки состояния элементов:
-1 – дополнительный корневой элемент (об этом ниже)
0 – элемент удален
1 – элемент добавлен
2 – свойства элемента изменились
3 – неизвестное состояние (на случай если что-то пошло не так)
4 – элемент не изменился
comm Комментарий, дающий дополнительные данные по состоянию

Для начала возьмем предыдущее и текущее деревья и скинем их в таблицу MR_ORDER_TREE_COMP. При этом добавим к ним общий корень, item_id у текущего дерева увеличим на (максимальное значение + 1) item_id дерева с предыдущим состоянием. Все элементы старого дерева будем считать удалением, а все элементы нового вставкой.

select nvl(max(item_id), 0) + 1
      into v_id
      from mr_order_tree_prev t
     where t.order_id = p_order_id;

    insert into MR_ORDER_TREE_COMP (ORDER_ID, ITEM_ID, KTS_ITEM_ID, ITEM_QTY, IS_ITEM_BUY, IS_ADD_WORK, ITEM_POSITION, N_GROUP, T_LEVEL, STAT, COMM)
                            values (p_order_id, -1, null, 0, 0, 0, 0, 0, 0, -1, 'Дополнительная голова для расчета');

    insert into MR_ORDER_TREE_COMP (ORDER_ID,
                                    ITEM_ID,
                                    ITEM_REF,
                                    KTS_ITEM_ID,
                                    KTS_ITEM_REF,
                                    ITEM_QTY,
                                    IS_ITEM_BUY,
                                    IS_ADD_WORK,
                                    ITEM_POSITION,
                                    N_GROUP,
                                    STAT,
                                    COMM)
    select p.order_id,
           p.item_id,
           nvl(p.item_ref, -1),
           p.kts_item_id,
           p.kts_item_ref,
           p.item_qty,
           p.is_item_buy,
           p.is_add_work,
           p.item_position,
           p.n_group,
           0,
           'удаление'
      from mr_order_tree_prev p
     where p.order_id = p_order_id;

    insert into MR_ORDER_TREE_COMP (ORDER_ID,
                                    ITEM_ID,
                                    ITEM_REF,
                                    KTS_ITEM_ID,
                                    KTS_ITEM_REF,
                                    ITEM_QTY,
                                    IS_ITEM_BUY,
                                    IS_ADD_WORK,
                                    ITEM_POSITION,
                                    N_GROUP,
                                    STAT,
                                    COMM)
    select p.order_id,
           p.item_id + v_id,
           case
             when p.item_ref is null
               then -1
             else p.item_ref + v_id
           end,
           p.kts_item_id,
           p.kts_item_ref,
           p.item_qty,
           p.is_item_buy,
           p.is_add_work,
           p.item_position,
           p.n_group,
           1,
           'вставка'
      from mr_order_tree p
     where p.order_id = p_order_id;


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

for rec in (select item_id,
             level lev
        from (select *
                from mr_order_tree_comp
               where order_id = p_order_id)
     connect by prior item_id = item_ref
       start with item_id = -1)
loop
  update mr_order_tree_comp c
     set c.t_level = rec.lev
   where c.order_id = p_order_id
         and c.item_id = rec.item_id;
end loop;

Сохраним состояние таблицы mr_order_tree_comp для пересчитываемого заказа, это понадобится в будущем. Я использовал коллекцию, но думаю, что можно применить и временную таблицу.

  procedure save_tree_stat(p_order in number)
  is
  begin
    select TREE_BC_STAT_ROW(c.order_id, c.item_id, c.item_ref, c.kts_item_id, c.kts_item_ref)
      bulk collect into tree_before_calc
      from mr_order_tree_comp c
     where c.order_id = p_order;
  end save_tree_stat;

«Сложение» деревьев


Теперь нужно пройти получившееся дерево по уровням и по узлам в поисках изменений. Для начала определим максимальный уровень:

select max(t_level)
  into v_max_lvl
  from mr_order_tree_comp
 where order_id = p_order_id;

Теперь в цикле пройдем уровни этого дерева. На каждом уровне, так же в цикле, будем выбирать дочерние элементы каждого узла, и искать элемент с «противоположным знаком». Проще говоря, искать одинаковые kts_item_id с одинаковым item_ref, но состоянием 1 для 0 и 0 для 1. После этого один из них удалять, а входящие элементы перецеплять на оставшийся узел.

Когда элемент обработан, помещать его в некоторый список обработанных элементов. Я использовал следующую процедуру:

  procedure add_to_rdy (p_item in number,
                        p_order in number)
  is
  begin
    item_ready_list.extend;
    item_ready_list(item_ready_list.last) := tree_rdy_list_row(p_order, p_item);
  end add_to_rdy;

«Обработанность» элемента возвращала функция

function item_rdy(p_item in number, p_order in number) return number

которая просматривала ту же коллекцию.

Цикл выглядит следующим образом:

<>
     for i in 1..v_max_lvl
     loop
       <>
       for rh in (select c.*
                    from mr_order_tree_comp c
                   where c.order_id = p_order_id
                         and c.t_level = i)
       loop
         <>
         for rl in (select c.*
                      from mr_order_tree_comp c
                     where c.order_id = p_order_id
                           and c.item_ref = rh.item_id
                           and c.stat in (0, 1)
                     order by c.stat)
         loop
           if (item_rdy(rl.item_id, rl.order_id) = 0) then
             if (rl.stat = 0) then
               select count(*)
                 into v_cnt
                 from mr_order_tree_comp c
                where c.order_id = p_order_id
                      and c.item_ref = rh.item_id
                      and c.kts_item_id = rl.kts_item_id
                      and c.stat = 1;

               case
                 when (v_cnt = 1) then
                   select c.item_id
                     into v_item
                     from mr_order_tree_comp c
                    where c.order_id = p_order_id
                          and c.item_ref = rh.item_id
                          and c.kts_item_id = rl.kts_item_id
                          and c.stat = 1;

                   update mr_order_tree_comp c
                      set c.item_ref = v_item
                    where c.item_ref = rl.item_id
                          and c.order_id = p_order_id;

                   update mr_order_tree_comp c
                      set c.stat = 4
                    where c.item_id = v_item
                          and c.order_id = p_order_id;

                   diff_items(p_order_id, rl.item_id, v_item);

                   delete mr_order_tree_comp c
                    where c.item_id = rl.item_id
                          and c.order_id = p_order_id;

                   add_to_rdy(rl.item_id, rl.order_id);
                   add_to_rdy(v_item, rl.order_id);
               end case;
             end if;

Для (rl.stat = 1) логика аналогична.

Когда нашелся такой же элемент, то всё просто — нужно просто сравнить их свойства. Для этого используется функция diff_items. Ситуация, когда найдено более одного элемента, является скорее исключением и говорит о том, что с деревом состава что-то не так.

Поиск «похожих» элементов


Но что делать, когда произошла замена одного узла на другой, был вставлен узел в середину или узел из середины был удален?

Для определения описанных ситуаций я не нашел ничего умнее как просто сравнить составы двух узлов с целью определения отношения количества одинаковых kts_item_id к общему количеству элементов. Если значение данного отношения больше определенного значения, то узлы взаимозаменяемы. Если на текущей итерации цикла у узла есть несколько вариантов замены, то берется вариант с наибольшим «коэффициентом похожести».

Возможно, таким смелым решением я когда-нибудь выстрелю себе в ногу.

Добавим немного кода в основной CASE.

when (v_cnt = 0) then
 select count(*)
   into v_cnt
   from mr_order_tree_comp c
  where c.order_id = p_order_id
        and c.item_ref = rh.item_id
        and c.stat = 1
        and not exists (select 1
                          from table(item_ready_list) a
                         where a.order_id = c.order_id
                               and a.item_id = c.item_id);

Удалось найти один элемент в этом узле

 if (v_cnt = 1) then
   select c.item_id, c.kts_item_id
     into v_item,    v_kts
     from mr_order_tree_comp c
    where c.order_id = p_order_id
          and c.item_ref = rh.item_id
          and c.stat = 1
          and not exists (select 1
                            from table(item_ready_list) a
                           where a.order_id = c.order_id
                                 and a.item_id = c.item_id);

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

   if (is_item_comp(v_item, p_order_id) = is_item_comp(rl.item_id, p_order_id)) then
     update mr_order_tree_comp c
        set c.item_ref = v_item
      where c.item_ref = rl.item_id
            and c.order_id = p_order_id;
     add_to_rdy(rl.item_id, rl.order_id);
     add_to_rdy(v_item, rl.order_id);
   end if;
 end if;

Если удалось найти несколько элементов, то берется наиболее похожая сборка. Для определения «похожести» используется процедура like_degree, значение коэффициента для сравнения содержится в переменной lperc.

if (v_cnt > 1) then
   begin
     select item_id, kts_item_id, max_lperc
       into v_item,  v_kts,       v_perc
       from (select c.item_id,
                    c.kts_item_id,
                    max(like_degree(rl.item_id, c.item_id, c.order_id)) max_lperc
               from mr_order_tree_comp c
              where c.order_id = p_order_id
                    and c.item_ref = rh.item_id
                    and c.stat = 1
                    and not exists (select 1
                                      from table(item_ready_list) a
                                     where a.order_id = c.order_id
                                           and a.item_id = c.item_id)
                    and is_item_comp(c.item_id, p_order_id) = (select is_item_comp(rl.item_id, p_order_id) from dual)
              group by c.item_id, c.kts_item_id
              order by max_lperc desc)
      where rownum < 2;
     if (v_perc >= lperc) then
       update mr_order_tree_comp c
          set c.item_ref = v_item
        where c.item_ref = rl.item_id
              and c.order_id = p_order_id;

       update mr_order_tree_comp c
          set c.comm = 'Удаление. Заменилось на ' || kts_pack.item_code(v_kts) || ' (' || to_char(v_perc) || '%)'
        where c.item_id = rl.item_id
              and c.order_id = p_order_id;

       add_to_rdy(rl.item_id, rl.order_id);
       add_to_rdy(v_item, rl.order_id);
     end if;
   end;
 end  if;

В итоге часть элементов будет перецеплена, и дерево будет иметь следующий вид.

Если дополнительный корневой элемент, который был добавлен в начале, не нужен, то его можно удалить.

Теперь можно взять все оставшиеся элементы со статусом 0 и 1, и начиная с них пройти вверх к корню. Если будет найден такой же элемент с «противоположным статусом», то сравнить их, удалить из дерева элемент с 0, а у элемента с 1 сменить статус.

<>
for rs in (select *
             from mr_order_tree_comp c
            where c.order_id = p_order_id
                  and c.stat in (0,1))
loop
  <>
  for rb in (select *
               from (select *
                       from mr_order_tree_comp c
                      where c.order_id = p_order_id) t
            connect by prior t.item_ref = t.item_id
              start with t.item_id = rs.item_id)
  loop
    select count(*)
      into v_cnt
      from mr_order_tree_comp c
     where c.item_ref = rb.item_id
           and c.kts_item_id = rs.kts_item_id
           and c.stat in (1,0)
           and c.stat != rs.stat;

    if (v_cnt = 1) then
      select c.item_id
        into v_item
        from mr_order_tree_comp c
       where c.item_ref = rb.item_id
             and c.kts_item_id = rs.kts_item_id
             and c.stat in (1,0)
             and c.stat != rs.stat;

      if (rs.stat = 0) then
        update mr_order_tree_comp c
           set c.stat = 4
         where c.order_id = p_order_id
               and c.item_id = v_item;

        diff_items(p_order_id, rs.item_id, v_item);

        update mr_order_tree_comp c
           set c.item_ref = v_item
         where c.order_id = p_order_id
               and c.item_ref = rs.item_id;

        delete mr_order_tree_comp
         where order_id = p_order_id
               and item_id = rs.item_id;
      end if;

      if (rs.stat = 1) then
        update mr_order_tree_comp c
           set c.stat = 4
         where c.order_id = p_order_id
               and c.item_id = rs.item_id;

        diff_items(p_order_id, rs.item_id, v_item);

        update mr_order_tree_comp c
           set c.item_ref = rs.item_id
         where c.order_id = p_order_id
               and c.item_ref = v_item;

        delete mr_order_tree_comp
         where order_id = p_order_id
               and item_id = v_item;
      end if;

      continue items;
    end if;
  end loop branch;
end loop items;

Теперь пройдемся по оставшимся элементам со статусом 0 и восстановим их прежние item_ref. Для этого используется коллекция tree_before_calc, в которую было сохранено начальное состояние дерева mr_order_tree_comp.

После этого дерево получает искомый вид.



Полагаю, что есть более красивые, быстрые и правильные способы сравнения деревьев. Это мой вариант и надеюсь, что он будет полезен кому-то и покажет, как можно делать или как не надо делать.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334384/


Метки:  

Security Week 30: Adups снова за свое, как закэшировать некэшируемое, в контейнерах Docker – опасный груз

Пятница, 28 Июля 2017 г. 23:29 + в цитатник
Эта история началась давным-давно, еще в прошлом году, когда исследователи из Kryptowire наткнулись на подозрительный трафик, исходящий из купленного по случаю китайского смартфона. Углубившись в прошивку аппарата, они выяснили, что система OTA-обновлений представляет собой натуральный бэкдор. Ну, и еще немножечко апдейтит прошивку, в свободное от шпионажа за пользователем время.

FOTA (firmware over the air), программный модуль от Shanghai Adups Technology Company отправлял куда-то в Китай буквально все: SMS-сообщения, IMSI и IMEI, журнал звонков, географические координаты устройства. На сайте Adups гордо заявлялось, что их чудненький FOTA используется на 700 млн устройств. В основном это китайские и не очень смартфоны, а также навигаторы, умные автомагнитолы и все прочие гаджеты с подключением к Интернету.

После неслабого скандала Adups заявили, что, во-первых, совсем даже не шпионили, во-вторых, вовсе не по заданию китайских госорганов, а, в-третьих, они не специально и больше так не будут. Прошел почти год.

И вот Kryptowire снова раскрыли тему злодейства Adups. Невероятно, но факт: наш герой продолжает в том же духе. Точнее, по-прежнему поставляет в Китай идентификаторы базовых станций, список установленных приложений, серийные номера SIM и IMSI. Проверено на двух моделях – Blu Grand M и Cubot X16S.

Главное во всем этом даже не то, что Adups не перестал шпионить, а что спустя год после «сеанса магии с разоблачением» их продукты кто-то продолжает использовать.

На BlackHat показали новый метод извлечения персональных данных из серверов

Новость. Хороша нынешняя конференция BlackHat в США и доклады на ней интересные. Вот, к примеру, наш человек из Лас-Вегаса пишет, что Омер Гиль из EY Advanced Security Center представил новый способ атаки на CDN-сервисы вроде Akamai и Cloudflare — взлом без взлома. Это когда при определенных условиях сервер выдает закэшированные страницы другого пользователя.

Исследователь описал механизм атаки следующим образом. Допустим, есть URL — 'www.example.com/personal.php', ссылающийся на контент с важными данными, которые кэшировать не полагается. Хакер вынуждает жертву выполнить запрос 'www.example.com/personal.php/bar.css' (для этого есть масса способов). Сервер на это выдает страницу 'www.example.com/personal.php' с важной информацией жертвы – куки-файлы-то у нее имеются. При этом кэширующий прокси справедливо расценивает 'www.example.com/personal.php/bar.css' как запрос на несуществующий, но подлежащий кэшированию файл bar.css и сохраняет вместо этого содержимое '/personal.php'.

Ровно такой же фокус можно провернуть с более чем 40 расширениями: aif, aiff, au, avi, bin, bmp, cab, carb, cct, cdf, class, css, doc, dcr, dtd, gcf, gff, gif, grv, hdml, hqx, ico, ini, jpeg, jpg, js, mov, mp3, nc, pct, ppc, pws, swa, swf, txt, vbs, w32, wav, wbmp, wml, wmlc, wmls, wmlsc, xsd и zip. После этого хакер спокойно заходит на искомый URL и получает из кэша страницу с введенными персональными данными – например, платежной карты. По опыту Гиля, кэшированные файлы в указанных сервисах хранятся около пяти часов. Хуже того, кэшированный запрос может содержать CSRF-токены, идентификаторы сессии, ответы на секретные вопросы, то есть это уже попахивает угоном учетной записи.

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

В контейнерах Docker научились прятать зловредов

Новость. Продолжают поступать кул сторис с конференции BlackHat USA. В этот раз участники разоблачили Docker. Этим моднейшим средством для отладки и развертывания приложений в среде виртуализации сейчас пользуются многие разработчики. Исследователи из Aqua Security показали, как можно внедрять в контейнеры Docker малвару, соорудив по сути двойное дно.

Для начала надо найти жертву – разработчика, использующего Docker для Windows. Потом следует вынудить его зайти на специальный сайт, где сидит вредоносный JavaScript, который создает на машине жертвы новый контейнер, втягивающий с репозитория вредоносный код. Его устойчивость на машине обеспечивается скриптом, сохраняющим контейнер при шатдауне и запускающим его во время загрузки Docker.

Временное решение проблемы – обновить Docker, разрешить сетевой доступ только аутентифицированным клиентам, заблокировать порт 2375 на интерфейсе виртуальной машины Moby Linux с помощью файрволла, а во избежание расползания вредоносного кода по сети отключить LLMNR и NetBIOS на всех компьютерах.

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

Древности


«Drop-1131»

Резидентный неопасный вирус. Стандартно заражает COM- и EXE-файлы при обращении к ним. Перехватывает int 1Ch и 21h. В зависимости от значения своего внутреннего счетчика довольно активно осыпает буквы на экране.

Цитата по книге «Компьютерные вирусы в MS-DOS» Евгения Касперского. 1992 год. Страницa 66.

Disclaimer: Данная колонка отражает лишь частное мнение ее автора. Оно может совпадать с позицией компании «Лаборатория Касперского», а может и не совпадать. Тут уж как повезет.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334378/


Метки:  

JetBrains MPS для интересующихся #2

Пятница, 28 Июля 2017 г. 23:14 + в цитатник

Йо-хо-хо!


В прошлом посте мы остановились на том, что мы умеем добавлять массив входных погодных данных, а точнее данные "Время + температура", слегка попробовали использовать Behavior и разобрались с концептами.
Пришло время делать что-то полезное, ведь пока все, что мы реализовали, можно было реализовать на любом другом языке, за исключением прикольного синтаксиса.
Первым делом, введем ограничения на время. Сейчас мы ограничим его, чтобы часы были в пределе 0-24, а минуты 0-60, иначе будет выдаваться ошибка компиляции.


Constraints


Constraints это аспект языка, который отвечает за валидность реализации концепта. В нашем случае нам нужно ограничить property hours и minutes, поэтому мы создаем Constraints аспект концепта Time.
image
Здесь мы видим 3 пункта, которые отвечают за структуру AST.


  • can be child: получаем на вход данные об узле, родительском узле, дочернем и все, что только можно и решаем, может ли реализация концепта в данном контексте быть дочерней или нет
  • can be parent: то же самое, что и с child, только проверка на возможность быть родительским узлом
  • can be ancestor: все то же самое, что с parent, но более вложенно: в данном случае мы можем идти как угодно выше по AST, дословно — может ли узел быть предком


    Дальше мы можем определить какие то характеристики для properties. Это то, что нам нужно, и пока этого знать вполне достаточно, возиться с областью видимости нам пока не нужно.
    image
    Все, в принципе, просто и понятно: мы можем переопределить геттер и сеттер, но нас интересует is valid. В нем мы на вход получаем propertyValue и текущий node. У нас простое условие, так и пишем, как писали бы на Java.
    image
    Теперь если мы соберем язык и потыкаем в sandbox, то у нас должно показывать, если значение часа >= 24 или <0.
    image
    Написать реализацию для minutes не составит труда Вам самим.
    Так, здорово, работает. Теперь стоит попробовать перевести это на Java, ведь не зря же мы это все делали!
    Сначала добавляем аспект Generator и называем его main.
    image
    Пустовато, поэтому создадим новый root mapping rule. Выбираем в поле concept наш рутовый концепт PredictionList, а справа от стрелочки — нажимаем Alt + Enter -> New Root Template -> Java class. По логике должно получиться что-то вроде этого:
    image
    Если мы откроем map_PredictionList, то у нас будет что-то вроде Java класса с мета информацией над ним.
    image
    Это наш темплейт, шаблон и вообще самый главный отправной пункт. Но есть один момент: мы же не хотим преобразовывать наш WeatherTimedData в какие то примитивы, верно? Мы хотим чтобы у нас объект класса WeatherTimedData, но тут бамс! У нас же нет такого класса! Так что мы можем написать его вручную. Для этого создадим новый Solution, называем его, как хотим, и самое главное — добавляем в Used Languages jetbrains.mps.baseLanguage, чтобы мы могли написать наши классы.
    image


    У меня они получились такие:



image


image


image


image


Теперь нужно научиться использовать это в наших генерациях в Java код. Заходим в model properties генератора и добавляем в dependencies WeatherClasses и нажимаем export=true.
Теперь мы можем использовать эти классы в генерации, что мы сейчас и сделаем.


image


Выглядит как простой класс, но нам нужно добиться того, что name будет иметь значение имени PredictionList. Прогноз погоды для питера — там будет питер. Для Москвы — будет москоу. Нажимаем на строку "Here should be city" и юзаем хоткей Alt + Enter и в выпадающем списке выбираем property macro.


image


Суть очень простая — нам дается node типа PredictionList и мы должны вернуть строку. Нажимаем на знак доллара, который появился рядом со строкой и редактируем код в инспекторе.
image


Собираем проект, открываем наш Sandbox solution, где у нас есть только входные погодные данные для Санкт Петербурга, нажимаем ПКМ -> Preview Generated Text, и у нас откроется настоящая Java! Теперь мы можем ее не скринить, а спокойно скидывать копипастом.


package WeatherPrediction.sandbox;

/*Generated by MPS */

import WeatherClasses.structure.PredictionList;

public class PredictionListImpl extends PredictionList {

  /*package*/ String name = "Saint Petersburg";
}

Стоит заметить import statement, MPS сгенерировал импорт PredictionList, которые мы писали отдельным Solution. Такие solution можно называть "помогающими", "support solutions". Ну мне лично очень нравится их так называть.
Ну давайте добавим еще реализацию для массива входных данных.


image
Мы создаем пустой linkedlist(почему бы и нет), в котором мы будем хранить входные данные.
В конструкторе мы используем сразу 2 крутых макроса.
Макрос $LOOP$ делает следующее: он проходит по данной коллекции, и для каждого элемента выполняет что-то. В итоге получается массив сгенерированных данных, которые просто идут друг за другом. В данном случае мы итерируем по node.weatherData.items
Макрос $COPY_SRC$ используется, чтобы получить результат преобразования в другую модель какого-то концепта. В данный момент у нас есть только 1 шаблон: он "главный" и он является шаблоном для PredictionList, и откуда же MPS поймет, что и как делать..?
В такие моменты MPS смотрит в конфигурацию генератора main, а точнее в reduction rules, где у нас сейчас пусто.
image
Делаем абсолютно то же самое, что делали с PredictionList.
image
Переходим в reduce_WeatherTimedData, нажимаем Shift + Space, выбираем Expression. Теперь просто пишем


new WeatherTimedData(0, 0, null)

Теперь нужно завернуть этот Expression в TemplateFragment, чье содержимое как раз таки и будет использовано в нашем главном PredictionListImpl.
Выделяем весь expression с помощью хоткея ctrl + w, нажимаем Alt+Enter -> Create Template Fragment.
image
Теперь нам нужно заменить нули на property macro, которые мы уже умеем делать(нажимаем на 0, нажимаем Alt Enter -> Add property macro. В инспекторе пишем


(templateValue, genContext, node, operationContext)->int { 
  node.time.hours; 
}

что соотвествует замене 0 на актуальное значение часов. Проделываем то же самое с минутами, а null заменять не будем — мне сейчас лень, но идея та же — мы добавляем reduction rule для концепта Temperature, и вместо property macro используем макрос $COPY_SRC$
После чего заменяем 0 и 0 на property macro, которое мы уже умеем вызывать(Выделяем 0, Alt + Enter ->Add Property Macro -> node.time.minutes).
Собираем язык и идем в Sandbox solution.
Итак, для исходного кода на языке Weather


Weather prediction rules for Saint Petersburg 
[ 0 : 23 ] { 
  temperature = 23.3 °C 
}  
[ 12 : 24 ] { 
  temperature = 100.0 °F 
}
[ 23 : 33 ] { 
  temperature = 4.4 °C 
}  

Получается такой Java код:


package WeatherPrediction.sandbox;

/*Generated by MPS */

import WeatherClasses.structure.PredictionList;
import java.util.Deque;
import WeatherClasses.structure.WeatherTimedData;
import jetbrains.mps.internal.collections.runtime.LinkedListSequence;
import java.util.LinkedList;

public class PredictionListImpl extends PredictionList {

  /*package*/ String name = "Saint Petersburg";
  /*package*/ Deque input = LinkedListSequence.fromLinkedListNew(new LinkedList());

  public PredictionListImpl() {
    LinkedListSequence.fromLinkedListNew(this.input).addElement(new WeatherTimedData(0, 23, null));
    LinkedListSequence.fromLinkedListNew(this.input).addElement(new WeatherTimedData(12, 24, null));
    LinkedListSequence.fromLinkedListNew(this.input).addElement(new WeatherTimedData(23, 33, null));
  }
}

Можно было бы заменить linkedlist на обычный массив, но это было бы сложнее, так как нужно было бы пихать индексы. Можно было бы заменить на ArrayList, но MPS первым посоветовал linkedlist. Можно было бы написать отдельный support-класс для WeatherData, а не добавлять данные в конструкторе, существует много способов сделать генерируемый код лучше. Или хуже. В общем, теперь мы умеем генерить (!)Java код из нашего языка. А вообще, теперь мы можем генерировать Java код для любого другого языка, ведь мы овладели знанием Generator!
Спасибо за внимание.

Я вообще понятно вещаю или стоит разжевывать сильнее?

Проголосовало 5 человек. Воздержалось 4 человека.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334376/


Метки:  

Инженерные системы малого офиса и вопросы к ним для само (и не само) проверки

Пятница, 28 Июля 2017 г. 22:09 + в цитатник
Внезапно для многих, в конце июля в Москве наступило лето. Вообще для многих лето — почти как зима для коммунальных и дорожных служб, ни разу не было и вот опять.
Одновременно в комментариях к заметке написали про необходимость помнить и про инженерные системы.

Исправляюсь, и пишу про них.

tl/dr: всякие мелочи, которыми админ заниматься не должен, но порой приходится, особенно в малом офисе. Или в дата-центре.

Итак — инженерные системы малого офиса.


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

Из нужных в ИТ систем стоит выделить:
— Воздухоподготовку (нагрев/кондиционирование/сушку)
— СКУД,
— электропитание,
— пожаротушение.

Кондиционирование, расчет тепловыделения и BTU (British thermal unit).
Обслуживание. Чиллеры.


Кондиционирование, т.е. теплоотвод, вещь в современном ИТ необходимая, по простой причине – при перегреве и длительной (месяцы) эксплуатации техники при температурном режиме выше +25 градусов – срок службы техники сокращается, иногда в разы (с 5-6 до 2-3 лет). То же самое касается влажности – избыточная влажность вредна, поскольку вызывает пусть незаметный, но конденсат, и как следствие – коррозию контактных площадок памяти, например. Разумеется, техника может работать и годами, просто стоя под столом, но скорее всего такая техника не проработает и три требуемых от нее года, и тем более не проработает пять.
Пример номер 1 — в конце текста.

Расчет тепловыделения техники прост – потребляемая мощность каждой единицы техники известна, примерно столько же мощности техника отдаст в виде тепла. Поскольку установка и расчет систем кондиционирования обычно отведена специальным людям, то все, что вам нужно сообщить им для первичного расчета – это мощность вашей техники в киловаттах. Потом конечно прибавятся стены\окна\прочее, но потом.
Можно, конечно, пересчитать киловатты в джоули/сек, потом и в джоули/час, оттуда пересчитать пересчитать в BTU/hr — British thermal unit, британская тепловая единица/час, но ничего сложного и специального в этом пересчете нет. К тому же кондиционеры выпускаются не индивидуально, мощность кондиционера выбирается из ряда мощностей, предлагаемых производителем, так что главное:

– не забывать что мощностей у кондиционеров две (по теплоотводу и по потребляемой мощности из сети).
— включать кондиционер к сети через отдельный предохранитель НА ФАЗЕ точно, но можно и двойным, на фазу и ноль одновременно.
— не забывать подписывать этот предохранитель прямо на щитке.

Помнить о том, что
— помпы (откачки конденсата) ломаются,
— каналы водоотвода зарастают не важно чем
— чиллеры могут не стартовать
внешние радиаторы нуждаются в ежегодной чистке перед началом летнего сезона, а там где березы и тополя – и после окончания цветения.
— переход зима-лето и лето-зима всегда требует проверки оборудования и возможной дозаправки хладагента.
— Помнить о резервировании N+1 – в том смысле, что система кондиционирования должна работать при 1 вышедшем из строя кондиционере неограниченно долго.

Мораль:
1. Мониторь термодатчики автоматом, лучше с двух точек. ИБП и скажем CISCO с термодатчиком, или сервер какой.
2. Не пренебрегай плановым осмотром утром и вечером. Да и в обед. Если есть охрана, то пусть и ночью пробежит, мало ли что там (например, посмотрит в специальное окошко на простой бытовой термометр). На одной площадке мне за пару лет охрана раза три звонила – перегрев, отказ кондиционера.
3. Заправляй/проверяй (в смысле выписывай специальных людей) кондиционеры два раза, весной и осенью, перед весной промой (керхером хотя бы), и после тополиного пуха и цветения березы тоже промой. Ну и перед зимой, после листопада.

— Помнить о контроле температуры и влажности в целом – и использовать системы от Nag

В 2015-м году они предлагали комплект –
SNR-ERD-GSM-1.1 — Устройство удалённого контроля и управления с GSM интерфейсом ERD-GSM, БП, корпус, антенна, крепление и ИБП к нему
плюс можно было взять датчики дыма, протечек, герконы и так далее.

Есть вот такой набор решений –
SNR-ERD: От “пинговалки” до линейки оборудования

Есть и альтернативы – Устройство NetPing DKST61-01
Устройство удалённого мониторинга датчиков по сети Ethernet/Internet. Позволяет удалённо получать информацию о состоянии 1-Wire датчиков и уведомления о срабатывании 1-Wire датчиков

Можно организовать контроль на ИБП, или использовать что-то типа NetBotz

Можно рассмотреть Sky Control

Полезное:
Режим работы тепловых насосов (кондиционеров) и выравнивание износа. Классический примерчик на тему «для чего нужно выравнивание наработки основного и резервного оборудования». И сам режим работы: читать

ИБП / UPS, Электропитание 220/380, 230/400 и даже иногда 127 В.
Защита от 380В.


Это то самое внезапно ненужное знание, когда минимум треть падаванов уверены, что в розетке, как и батарейке, есть плюс и минус, а 380 – чтото страшное и ужасное.
На самом деле надо было учиться в школе и институте, и запомнить, что:
Сетевое напряжение — среднеквадратичное (действующее) значение напряжения в электрической сети переменного тока
В СССР в электрических сетях общего назначения использовался трёхфазный ток с межфазным напряжением 380 В и напряжением фаза-нейтраль 220 В. Согласно межгосударственному стандарту ГОСТ 29322-92 (МЭК 38-83/IEC 60038:1983), в России к 2003 г. предписывался переход на номинальное напряжение 230/400 В. По обновлённому ГОСТ 29322-2014 (IEC 60038:2009), сетевое напряжение должно составлять 230/400 В при частоте 50 Гц ±10 %.

Что почитать по теме.
В обязательном порядке: ПУЭ — Правила устройства электроустановок ПУЭ текущей редакции (на 2016 год – 7е издание, Минэнерго России От 08.07.2002 № 204).

Так что в розетке у вас не плюс и минус, а фаза (т.е. тот провод, где электричество есть) и нейтраль (где электричества быть не должно, но немного есть).
Иногда (но все реже) встречается и сеть 127/220, что означает разницу между фазой и нолем в 127 В, а между 2 фазами – 220 В. В результате в обычную розетку заводятся две фазы. В таких помещениях в розетки обязательно должно быть заведено заземление, а само заземление должно быть проверено специально обученными людьми.
Примечание:
Следует отличать TN-C от TN-S, а их оба от TN-C-S

и понимать, почему в США в розетке для стиральной машины может оказаться две фазы и земля.
И прочитать статью Система заземления «TN-S»

Что касается автоматов выключения, то тут ничего сложного нет. Обычный однофазный автомат маркируется как A/B/C(N) – например C16, где C- класс устройства, 16 – это максимальный ток в амперах. Следует помнить, что, хотя в сети переменного тока присутствует разнообразный мнимый элемент и косинус фи, но для сетей с малым током и малым сдвигом фаз — мощность можно рассматривать как P = U*I, и для 6 ампер / 220 вольт максимальная мощность составит всего 1.3 киловатта. Для понимания, у электрочайника 1.5-2 киловатта мощности.
Про классы (A/B/C/D) и номинальный ток срабатывания знать конечно можно, но не обязательно, не электрики. Хотя и «типаэлектрики» умудряются этого не знать.
Читать тут

УЗО и дифавтоматы
Лучше прочитать про него отдельную статью – хоть про УЗО, хоть про residual current device, хоть про residual-current circuit breaker. Про ток отключения, типы A/AC, селективные УЗО и так далее. Вещь, безусловно, нужная, как и дифавтоматы.

ИБП / UPS.
Бывает так, что электричество внезапно заканчивается, иногда даже во всем районе или городе. Причин может быть много, от умелой работы самого страшного врага для ИТ – экскаватора, до пожара на подстанции и нехваткой мощности на город в целом.
По статистике, чаще всего электричества нет не больше чем 1-2 минуты, пока наследие СССР в виде единой энергосистемы (не самое плохое наследие, а даже и очень хорошее) переключает питание на другую ветку/луч. Впрочем, бывают и другие случаи, тогда электричества может не быть часы, и даже дни.

В первом случае (короткие перерывы в подаче электроэнергии) помогает ИБП / UPS.
Что надо помнить:
— Наличие любого ИБП лучше его отсутствия.
— Линейно-интерактивный (Line-Interactive) с автотрансформатором (AVR — Automatic voltage regulator) лучше Off-Line
— ИБП с двойным преобразованием вообще хорошие, но дорогие.
— при расчетах тепловой мощности ИБП надо учитывать.
— мощность, которую фактически в ПИКЕ выдает ИБП, последние лет 10 производители писать перестали, так что подбор нужного по мощности ИБП – тема отдельной статьи, их написано десятками.

Что надо ОБЯЗАТЕЛЬНО знать ИТ-шнику про ИБП/UPS APC/Delta/HP
Сброс пароля на APC 9619/9639 – правильный шнурок, скорость, два тыка в кнопку.
ВНИМАНИЕ! Неправильный выбор шнурка на APC ведет к выключению ИБП! Причем разъем выглядит точно также, смотрите разводку и не теряйте нужный шнурок, и лучше ПОДПИСЫВАЙТЕ! НУЖНЫЕ шнурки. Они там минимум двух (с com и штырем) типов.

Статические и динамические ИБП.
Статические ИБП: все просто. БОЛЬШАЯ батарейка и преобразователи (инверторы).

Динамические ИБП.
В малом офисе не встречаются. Устроены просто — БОЛЬШАЯ и высокоскоростная болванка, подключенная (физически) к генератору, и к дизелю.
Сначала генератор крутит болванку, потом (при потере напряжения) болванка крутит генератор.
Если дизель не завелся, то (у некоторых производителей) в какой-то момент болванка через (автоматическую электромагнитную) муфту проворачивает дизель, и дальше уже дизель крутит болванку и генератор.

АВР (автоматический ввод резерва). Дизель-генераторы.
Заземление. Техника электробезопасности.


Автоматический ввод резерва. Вещь полезная, если
— в здание есть два ввода
— до помещения с серверной тоже заведено два ввода,
— ИБП умеет питаться от двух вводов сразу.
Что надо понимать:
— АВР – не замена ИБП, в лучшем случае это замена необходимости покупать дизель.
Примером АВР будет устройство типа
APC AP7723 RM 1U Automatic Transfer Switch автопереключатель на резервное питание
Примечание: существует терминологическая путаница. Иногда под АВР понимается автозапуск дизелей.

Дизель-генераторы.
В малом офисе не встречаются.

Заземление. Техника электробезопасности.
Заземление.

Вещь, на самом деле необходимая. В том числе и в виде заземляющих браслетов на технике. За подробностями зачем именно оно надо – читайте учебник физики и ПУЭ, по факту в здании оно должно быть и должно быть проверено. Проверено оно или нет – узнавайте у главного электрика/энергетика, он знает. Если не знает – то считайте заземление отсутствующим и пишите служебные записки руководству, что без заземления жить нельзя.

Техника электробезопасности.
Тут все очень просто – знай свое хозяйство. Одним из первых дел при устройстве на новое место работы – это проверка электропитания. Выясняйте, где тут электрощит, отвечающий за розетки серверного и рабочего оборудования, какие там автоматы, есть ли УЗО, что было с электропитанием раньше и как часто автоматы срабатывали по перегрузке. Проверьте, что все ваши розетки подписаны по месту, а над щитком с вашими автоматами есть надпись «автоматы группы ИТ». В самом неприятном случае никто не будет искать «журнал учета распределения групп аварийных выключателей». Кстати, если комната на ключе, то лучше всего убедиться, что ключ находится в зоне доступности, у охраны или в известном помещении электриков, и не реже раза в квартал проверять, что ключ еще на том же месте, и что это точно тот ключ, и он открывает эту дверь. И кстати, перед электрощитовой стоит держать углекислотный огнетушитель.

Про криворуких. И факапы.
ВСЕГДА! ВСЕГДА!!! проверяйте за этими криворукими электриками, чтобы они, нехорошие люди, многожилку заводили в гильзу!
Реальный случай, к слову. Электрики по лени (потому что гильзы БЫЛИ. В неприметном пакетике сбоку, но БЫЛИ) завели многожилку под клемный винт.

ВСЕГДА носите с собой отвертку-тестер (индикаторную отвертку).
ВСЕГДА проверяйте отверткой корпуса, ДАЖЕ после того как отключили питание.
ПУЭ прямо предписывает проверку сначала тестером, потом тыльной стороной ладони, и только потом трогать.
Реальный случай – вместо земли в розетке была фаза, и от корпуса техники било током.
Другой реальный случай – криворукие электрики проложили провода под крепежом внешнего (уличного) блока, провод перетерся – фаза на корпусе – труп.
При том, что техника «вроде бы» была отключена.
Фаза может быть в просто давно свисающем проводе.
Провода могут быть перепутаны в щитке.
Будьте осторожны, берегите себя. Чтите ПУЭ.

СКУД и прочая безопасность.
В случае ИТ чаще всего СКУД бывает двух видов – видеорегистраторы и системы контроля доступа на картах типа Proximity/Em-marin.
Видеорегистраторы ничего особого из себя не представляют – это аналоговые камеры с аналоговой линией, плюс конвертеры из аналогового в цифровой формат (практически ТВ-тюнер), пишут на жесткий диск сервера.
Второй вариант — цифровые камеры, которые передают данные сразу в цифровом формате (по ip) на сервер видеонаблюдения. Чаще всего уже установлены и настроены, выбор «что и как» меняется каждый год, так что универсальных советов по данной технике нет. Кроме советов «как для любой техники» — изолировать от остальной сети (видеосерверу нечего делать в интернете и в локальной сети), использовать ИБП и резервное копирование.
POE и прочее питание лучше развязывать с общей сетью, изучить тему «грозозащита» и «оптогальваническая развязка».

СКУД, например тот же Болид, представляет из себя систему «сервер — com-порт – считыватель». В сервере хранятся фотографии, уникальные номера карт, пароли к ним (если нужны) и схемы «что где стоит». В контроллер по ком-порту через прилагаемое ПО медленно и печально эти данные отправляются, далее номера карт хранятся уже в контроллере. Для управления и обслуживания никаких особых навыков не требуется.
Раньше у Болида были однодневные курсы «что это такое и как работает».

Системы газового, порошкового и Novec 1230 – пожаротушения.
Противогазы изолирующие и фильтрующие.


Перед тем, как говорить о системах пожаротушения, стоит вспомнить о системах оповещения. Чаще всего это ряд коробочек под потолков с датчиками дыма (срабатывают на пыль) и датчиками температуры (на сплаве Вуда, не срабатывать там нечему).
Для системы водяного тушения используют клапаны с закрытием стеклянной колбочкой с жидкостью.

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

Поведение при пожаре.
Поведение при пожаре для сотрудника описывается в типовой инструкции, с которой ответственный по технике безопасности приходит к каждому новому сотруднику и знакомит под роспись. Чаще всего поведение сотрудника описывается двумя пунктами:
— при личном обнаружении пожара – оповестить окружающих, включить пожарную тревогу, эвакуироваться согласно плану эвакуации, вызвать пожарную команду.
— при срабатывании пожарной сигнализации – эвакуироваться согласно плану, вызвать пожарную команду.
— иногда у руководителя отдела стоит в инструкции пункт «посчитать выбежавших и убедиться что из отдела все эвакуировались».

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

Системы пожаротушения.
Система порошкового тушения – это, фактически, коробка с килограммом (и более) мела. Для установки в серверной не пригодна, поскольку оборудованию после применения такой системы скорее всего будет капуууууууут.
Система газового пожаротушения – в помещении ставится бронированная пожаро-газо-проче- стойкая дверь, а в помещении баллон с азотом. При срабатывании системы в помещение поступает азот, который вытесняет кислород и гореть становится нечему. Есть некоторые проблемы с ростом давления, но этот момент надо уточнять еще при проектировании установки такой системы. Главная проблема – при срабатывании этой системы надо немедленно убежать, поскольку человек дышит кислородом, и без него живет минуту-две. Наличие изолирующего противогаза с регенерацией – по желанию.
Есть проблема выхода из строя оборудования от шума и вибрации при срабатывании системы.
Системы пожаротушения на Novec 1230.
Фактически газовая (хладоновая) система, но более мягкая по давлению и действию на случайно попавший в зону тушения человеческий организм. Можно успеть убежать.
Почитать про нее можно например на Хабре: тут или вот тут

Противогазы изолирующие и фильтрующие.
1. В зону пожара лезть не надо НИКОГДА.
2. Из зоны применения систем пожаротушения надо НЕМЕДЛЕННО УХОДИТЬ.
3. Фильтрующие противогазы, респираторы и так далее в зоне применения систем пожаротушения НЕПРИМЕНИМЫ. Там нет кислорода – он весь вытеснен газовой смесью.

Прочие инженерные системы. Строительство в целом.
Планирование размещения и транспортировки оборудования.
Из прочих инженерных систем мне попадалась разве что старая телефония, на 50-парниках и разведенная в такие же старые шкафы.
Часто бывает на старых заводах, например. Иногда даже работает.
Иногда на нее завязан ОЧЕНЬ ВАЖНЫЙ сервис. Который нигде не документирован – например сигнализация, или 20 лет назад установленный ADSL. Будьте осторожны при отключении.

Строительство в целом. Планирование размещения и транспортировки оборудования.
Про необходимость этого короткого абзаца мне напомнила известная история – «Выпуск 3. Чудо-богатыри». Очень рекомендую найти и прочитать, дважды. Так вот, проблема техники и шкафов в том, что шкафы (особенно ИБП, размерами от симметры и выше) – реально тяжелые. Полтонны – легко. Бывает больше.
Набитый шкаф может весить тонну. Соответственно – проектируйте, учитывайте и контролируйте и несущую способность пола, и что у вас фактически подходит к розеткам (например, не проложено ли у вас старое алюминиевое рассыпающееся говно), и как вы будете организовывать занос\вынос шкафа из вашего помещения. 120-150 кг пустой шкаф.

Для продвинутых сотрудников – при проектировании надо помнить о таких вещах, как поэтажные планы, с указанием электропроводки, всяких каналов, отопления, воздуходовод, воды всякой и канализации. Желательно, конечно, держать копию всех схем у себя и дружить со службой эксплуатации здания – сантехники, электрики, службы контроля всяких пожарных дымоуловителей и прочих извещателей, телефонисты, кондиционерщики и так далее.

Что почитать:
ПУЭ — Правила устройства электроустановок ПУЭ текущей редакции (на 2016 год – 7е издание, Минэнерго России От 08.07.2002 № 204).
Болид – вводный курс по СКУД.
Строительные нормы и правила (СНиП)
ГОСТ Р 50345-2010: Аппаратура малогабаритная электрическая. Автоматические выключатели для защиты от сверхтоков бытового и аналогичного назначения. Часть 1. Автоматические выключатели для переменного тока
МЭК 60898-1:2003* (издание 1.2) «Аппаратура малогабаритная электрическая. Автоматические выключатели для защиты от сверхтоков бытового и аналогичного назначения. Часть 1. Автоматические выключатели для переменного тока» (IEC 60898-1:2003 «Electrical accessories — Circuit-breakers for overcurrent protection for household and similar installations — Part 1: Circuit-breakers for a.c. operation»).

Пример номер 1. Перегрев где не ждали:

Дано: HDD Seagate
Seagate Enterprise Capacity 8 Tb SATA
ST8000NM0055-1RM112

Симптомы: скорость падает до «почти ноля» на ровном месте.
В диагностике ничего.

Asus P8H77-I (Intel H77 «Panther Point»), i5, 16 Gb, встроенный AHCI контроллер в режиме таки AHCI, не RAID, WS2016. Конфигурация дисков:

SATA3: 2x8 Tb Seagate новенькие = Storage Space Mirrored
SATA2: 3x2 Tb Seagate, WD = Storage Space Single-Parity; 1x300 Gb WD = System

Оба Storage Space дедуплицированы.

Проблема: после добавления новых двухтерабайтных сигейтов, система при многопоточной нагрузке на запись демонстрирует следующий сбой: время ответа дисков (всех, включая системный) растёт до 6-7 секунд, очередь дисков падает до 0, скорость записи падает до 5 Мб/с, система начинает очень плохо откликаться. Если используется буферизуемая запись, ОС выжирает под кэш записи весь доступный объём памяти. Когда система входит в такой режим, она выходит из него только ребутом, т.е. остановка дисковых операций и ожидание освобождения кэша не спасает.

Проблема проявилась только после подсоединения новых дисков. С размером тома (не физического устройства) она точно не связана, т.к. на этой системе успешно эксплуатировался Storage Space в 12 Тб (4х4 Тб Single Parity).

Драйверы AHCI контроллера пробовал встроенные и две версии от Intel (2013, 2014 годы, 12 и 13 мажорные версии).

Антивируса нет (встроенный удалён вообще, не отключён, а удалён). ОС свежая (переустановили начисто в ходе разбирательств до обращения ко мне), не трипперная, патченная, лицензионная.

Из софта Veeam B&R 9.5U2, проявлялось ещё до его установки.

Длительное копание во всем, и -(!!!) причина — перегрев.
Слова владельца системы:

55 градусов
1 градус вверх — и описанные симптомы
1 градус вниз — и всё збс как ни в чём не бывало
чёткая граница
причём 60 градусов у него прописано в SMART как threshold перегрева — но начинает троттлить в 55

UPD.
Вопросы по инженерным системам, без ответов.

Лично я считаю, что ответы на все эти вопросы должен знать любой сотрудник, любой эникей. И даже инфобезопасник (и немного майнер).

Зачем в серверных вообще нужно кондиционирование, если ПК сотрудников отлично работают и без него.
Зачем на кондиционере нужна помпа.
Сколько раз в год нужно проводить обслуживание кондиционера и почему.
Зачем на кондиционере нужен зимний пусковой комплект.

Электричество
Сколько проводов заходит в стандартную розетку и почему?
Как определить, где в розетке ноль и фаза, хотя бы два способа.
Для чего нужен провод с пятью проводами в нем?
Что означает цифра 6 в маркировке C6 на автомате? И, кстати, как это связано с тем, что при включении чайника этот автомат постоянно срабатывает?
Зачем нужно УЗО.
Что такое ИБП в общих чертах и зачем он нужен?

Пожаробезопасность
Что нужно делать при обнаружении пожара
Что нужно делать при срабатывании системы оповещения о пожаре?

Электробезопасность.
Почему удлинители — «пилоты» на рабочем месте, это плохо?
Почему пройдя мимо и увидев лазерный принтер, включенный в «тройник» надо остановиться, и что нужно объяснить тем, кто работает в комнате?
Что надо сказать, увидев что сотрудники вскладчину купили чайник и микроволновку?
Почему увидев разломанную розетку стоит написать докладную в 2 экземплярах и убедиться что одна копия пришла главному электрику, а вторая непосредственному руководителю?

Из реальной практики – 1. Вас как-то очень душевно приложило электричеством от корпуса шкафа, в котором стоит сетевое оборудование. Каковы ваши действия? Что надо носить с собой при такой работе?

Статическое электричество.
Сталкивались ли с статическим электричеством?
Что произойдет с микросхемой при проходе статики через нее?
Для чего нужен антистатический браслет?
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334370/


Метки:  

[Перевод] Как следить за опознанными летающими объектами при помощи Raspberry Pi

Пятница, 28 Июля 2017 г. 19:42 + в цитатник

А вы знали, что при помощи Raspberry Pi можно следить за опознанными летающими объектами? Вы можете настроиться на радио-сигналы самолетов на расстоянии до 400 км от вас и отслеживать все рейсы. Для этого вам достаточно найти дешевый USB TV и пару свободных минут.


dump1090


Изображение: dump1090 — тестирую антенну FlightAware против четвертьволновой гибкой антенны и антенны из банки.


В этой статье вы найдете краткое введение в отслеживание рейсов: обзор софта, аппаратуры и — самое главное — необходимой терминологии и жаргонных выражений. Также я покажу, как Docker и технология контейнеризации помогут управлять софтом в IoT-проектах.


На сайтах типа FlightAware.com можно отслеживать десятки тысяч самолетов при помощи краудсорсинга: задачу выполняют люди по всему миру с помощью своих компьютеров Raspberry Pi (цена вопроса — $35) и дешевых USB TV тюнеров.


Можно следить за рейсами исключительно в личных целях, а можно внести свою маленькую лепту на таких сайтах, как FlightAware.com, FlightRadar24 и PlaneFinder.net и получить взамен детальные показатели — данные радаров и другие ништяки.


FlightRadar


Изображение: FlightRadar показывает самолеты в воздушном пространстве Великобритании.


Зачем отслеживать рейсы?


Вот несколько доводов:


  • Это супер-дешевое приложение, которое можно применить на практике к вашему старенькому Raspberry Pi в пыльной кладовке.
  • Можно стать местным лидером по отслеживанию рейсов, если передавать эту информацию в онлайн-трекеры.
  • Можно собрать детальную статистику и подобрать лучшую антенну и место, где ее разместить.
  • Можно не только собирать данные для своих программных проектов, но и одновременно узнать много интересного об авиации.

И самое главное — это просто веселый проект, который можно провернуть при помощи своего Pi и получить моментальное удовлетворение от каждого кусочка. При этом затраты на него стремятся к нулю.


Что нам понадобится


  • Raspberry Pi, SD-карта с Raspbian Lite
    • Лучше используйте Raspberry Pi 2 или 3, потому что у них больше памяти и они лучше подходят для многозадачности.
    • Если вы пытаетесь установить несколько приемников и сэкономить, то Pi Zero тоже вполне подойдет.
  • USB TV Tuner — цена вопроса от 8 до 30 долларов.
    • FlightAware Pro Stick от ModMyPi — самый крутой вариант со встроенным шумовым фильтром, SMA-разъемом. Антенну на 1090 МГц надо покупать отдельно.
    • Generic DVB-T USB tuner from Pimoroni — мне прислали образец для тестирования. Работает хорошо, чипсет правильный, но телескопическую антенну надо установить в самый маленький разъем.
    • NESDR Smart Premium SDR — включает 3 антенны, толстый SMA-кабель и встроенный шумовой фильтр для городской среды.
    • Если вы хотите сэкономить, то на eBay полно гораздо более дешевых вариантов, но при выборе будьте внимательны: прибор должен работать на чипсете R820T.

Если нужен результат, лучше покупайте технику (DVB-T sticks) известных брендов. Представленные выше ссылки — не пиар по партнерке.


  • Антенны
    К большинству DVB-T тюнеров прилагаются антенны, которые скорее ловят сигналы TV на суше, а не нужные нам сигналы ADS-B на частоте 1090 мГц.
  • Если вам нужна антенна на 1090 мГц, можете купить домашнюю версию 3 dBi с функцией SMA. Антенна, которую я тестил, улавливала рейсы на расстоянии 240 км, если ее положить на подоконник.
  • Антенна FlightAware ловила сигнал в застроенной местности еще круче, на расстоянии свыше 400 км, когда я ее вывесил за окно. Говорят, результаты будут еще круче, если разместить ее на крыше.
  • Также вам понадобится источник питания на 2.5-3 Ампера, чтобы хватило на Pi и TV-тюнер наверняка. Можете подобрать себе что-нибудь на официальном сайте Pimoroni, поставщика приборов электропитания.

На сайте ModMyPi также можно купить весь необходимый набор в одном флаконе.


Глоссарий


Итак, наша цель — настроить USB TV тюнер таким образом, чтобы он ловил ADS-B трансляции рейсов в заданном диапазоне. Для начала давайте определимся с некоторыми определениями и терминами из области отслеживания рейсов.


ADS-B


На борту современных самолетов есть автоматические транспондеры, которые собирают информацию с навигационных инструментов и транслируют ее в окружающую среду через ADS-B. Эта информация не зашифрована, так что подхватить ее может любой — что диспетчер, что другой самолет, что владелец Raspberry Pi.
ADS-B (Automatic dependent surveillance-broadcast, автоматическое зависимое наблюдение-вещание) — технология, позволяющая и лётчикам в кабине самолета, и авиадиспетчерам на наземном пункте наблюдать движение воздушных судов с большей точностью, чем это было доступно ранее, и получать аэронавигационную информацию. Источник — Википедия.


DVB-T


TV-тюнер, который нам понадобится, называется DVB-T, что расшифровывается как Digital Video Broadcasting — Terrestrial. Это европейский стандарт эфирного цифрового телевидения. Это устройство также можно использовать как теле-антенну для просмотра любимых ТВ-шоу. Не все устройства DVB-T можно настроить на авиа-сигналы, так что лучше выбирайте что-то из рекомендованного или же тщательно изучите характеристики сами перед покупкой.


Антенный разъем SMA


Википедия: sub-miniature version A. Такие разъемы меньше коаксиальных и обычно есть у премиальных или целевых DVB-T. У дешевых DVB-T, скорей всего, будет маленький разъем. Пигетйл можно купить на eBay или в любом магазине электроники. Он понадобится, чтобы совмещать любые крупные антенные разъемы — коаксиальные, SMA или RF.
FlightAware Pro Stick


dump1090


FlightAware


Ключевой компонент для расшифровки сигналов ADS-B — это софт dump1090. Это число означает частоту, на которой мы работаем, а dump — команда, которую он выполняет — расшифровывает и дампит необработанные данные.


Приложение dump1090 — это open-source проект, у которого есть несколько форков благодаря разным людям, которые вносили новые и улучшали старые функции. Выбрать нужный форк может быть довольно затруднительно.


Я воссоздал историю этого приложения по данным с GitHub:


  • Antirez запустил проект в 2012 году на рождественских каникулах
  • MalcolmRobb принял эстафету — запустил новый форк в коде и улучшил некоторые функции
  • Mutability запустил форк от работы MalcomRobb-а
  • FlightAware также поддерживает форк от репозитория mutability

Мы будем использовать Docker для сборки кода, но при желании вы можете точно так же запускать команды отдельно в терминале. Вот несколько причин, почему стоит пользоваться Docker-контейнерами:


  • Воспроизводимые build-скрипты
  • Дают надежный механизм сборки кода, намного более удобный, чем страницы README
  • Позволяют переключаться между разными версиями кода
  • Напрямую на наш Pi ничего не ставится, поэтому прибор остается в исходном виде
  • Позволяют расшарить образ с друзьями, у которых есть Pi

У большинства версий dump1090 также есть веб-интерфейс, где можно увидеть самолеты в определенном диапазоне в режиме реального времени.


FlightAware


FlightAware — это один из нескольких сайтов-агрегаторов, которые собирают данные с программы dump1090.При помощи виртуальной визуализации радара вы можете собрать детальную статистику по тем рейсам, которые вы помогли отследить, а также узнать, в каком диапазоне вы работали.


Вот мои результаты, которые я увидел в своем профиле. Я использовал выделенную антенну и тюнер DVB-T с шумоизоляцией.


positions reported by distance


Также вы можете посмотреть мой профиль на FlightAware, чтобы получить больше данных.


MLAT


MLAT (аббр. мультилатерация) — это технология, при которой можно использовать некоторое количество наземных станций, чтобы отслеживать самолеты, которые не передают данные ADS-B. Можно почитать подробнее в статье на сайте FlightAware.


Она основывается на оценке разности времени прихода сигналов: она должна работать из коробки, и поэтому позволяет вам отслеживать намного больше рейсов, чем вы смогли бы при помощи одного только ADS-B.


Установка софта


  • Ставим Docker.
    Мы будем использовать Docker-образ, чтобы получить воспроизводимы build различных компонентов, которые нам нужны, и в то же время держать все дополнительные бинарники вне файловой системы хоста.
  • Клонируем GitHub-репозиторию:
    $ git clone https://github.com/alexellis/eyes-in-the-sky
  • Заносим в blacklist USB TV stick
    Чтобы dump1090 смог получить доступ к USB TV stick, нам надо внести его модуль ядра в черный список.

Добавляем эту строку в /etc/modprobe.d/blacklist.conf:
blacklist dvb_usb_rtl28xxu


Теперь перезагружаемся.


Декодер dump1090


enter image description here


Изображение: тестирую DVB-T от Pimoroni, прикрепленный к Pi Zero и оставленный дома у родственников.


  • Строим образ dump1090
    Если вы хотите ввести свою позицию (широту и долготу), то отредактируйте последнюю строчку в Dockerfile.malcolmrobb, которая начинается с CMD. Вы можете определить свою позицию по Google Maps.
    $ cd eyes-in-the-sky/dump1090
    $ docker build -t alexellis2/dump1090:malcomrobb . -f Dockerfile.malcolmrobb

‘-t’ — устанавливает название образа для дальнейшего использования.


-f — позволяет выбрать Dockerfile с кастомным названием. Также я задал имя для форка mutability.


Docker позволяет вам расшарить свои образы с кем угодно при помощи команды push, которая выгружает их на Docker Hub. Чтобы скачать dump1090 без сборки кода с нуля, выполняем команду:


$ docker pull alexellis2/dump1090:malcolmrobb

  • Тестируем образ dump1090
    Теперь можно и потестить.

$ docker rm -f 1090 # remove any old container

$ docker run --privileged -p 8080:8080 -p 30005:30005 -p 30003:30003 --privileged --name 1090 -d alexellis2/dump1090:malcomrobb

Команда docker run отвечает за запуск нашего кода. Чтобы потом код остановить, используйте docker rm -f 1090, а если вы перезагрузили Pi — restart 1090.


При помощи -p Docker определяет, какие порты надо раскрыть из контейнера. Можно запустить две копии кода dump1090, если поменять номер порта и имя контейнера.


При помощи -d контейнер перемещается в фон в качестве демона, так что если вы хотите увидеть консольный вывод, просто напишите ‘docker logs --tail 20 -f 1090’


Пример логов:


logs


Если вы знаете IP-адрес вашего Raspberry Pi, то вы можете открыть его во встроенной странице: http://192.168.0.10:8080/


Чтобы узнать IP-адрес, напишите ifconfig.


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


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


Если вы не хотите запускать контейнер с привилегиями, то вы можете узнать ID устройства USB, а затем заменить --privileged на --device=/dev/bus/usb/001/004, например.


Для своего случая вам следует заменить последние цифры, т.е. 004 в моем примере. Нужные цифры вы можете получить при помощи команды lsusb:


$ lsusb
Bus 001 Device 004: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T

Устанавливаем FlightAware


Есть несколько сайтов по отслеживанию рейсов, я начал с FlightAware. Их софт подключается к вашему коду dump1090 и передает данные в их сервера, где вы уже можете сверять статистику и сравнивать свои данные с другими участниками.


Можно установить .deb файл прямо на свой Pi, но я создал отдельный Dockerfile. У него есть два преимущества: можно запустить две и более копий софта и переключаться между версиями без перепрошивки Pi.


Дальше собираем образ при помощи следующей команды или скачиваем образ при помощи docker pull alexellis2/flightaware:3.5.0:


$ cd eyes-in-the-sky/flightaware
$ docker build -t alexellis2/flightaware:3.5.0 .

Обратите внимание на точку в конце строки, не пропустите ее.


Теперь регистрируемся на сайте FlightAware.com и задаем имя пользователя и пароль.


Редактируем файл piaware.conf, заменяем следующие поля:


  • receiver-host (используйте IP-адрес вашего Pi)
  • flightaware-user
  • Flightaware-password (используйте данные, которые указали при регистрации)

У FlightAware есть классная функция, которая позволяет отслеживать ваш Raspberry Pi по MAC-адресу. К счастью, Docker позволяет подменять MAC-адреса, и поэтому мы можем запустить несколько копий софта. Если вы так делаете, просто поменяйте MAC, чтобы он был уникальным для каждой копии.


Теперь запустим образ и посмотрим логи:


$ cd eyes-in-the-sky/flightaware
$ docker rm -f piaware_1
$ docker run --mac-address 02:42:ac:11:00:01 -v `pwd`/piaware.conf:/etc/piaware.conf --name piaware_1 -d alexellis2/piaware:3.5.0

Посмотрите логи и нажмите Control + C в любой момент времени.


$ docker logs --tail 20 -f piaware_1


Ваш Pi появится на сайте через несколько минут.


Ответы на вопросы


  • Какой будет расход электричества?
    Pi Zero или 2/3 потребляет 2-3 Ватта во время простоя. Приложение dump1090 задействует процессор Pi, до 50% его мощностей на Zero, поэтому учитывайте, что будет расходоваться дополнительное электричество для нагрузки и USB DVB-T.


  • Можно ли провернуть операцию с USB-аккумулятора?
    Да, в течение ограниченного времени. Аккумулятор, которого мне обычно хватало на 3 дня, ушел за 3 часа, когда я с его помощью отслеживал рейсы.


  • Можно ли использовать солнечную энергию?
    Солнечная энергия, возможно, — не совсем правильное решение. Raspberry Pi не будет надежно работать напрямую от солнечной панели. Вам понадобится сложное оборудование, включая контроллер зарядки, солнечные панели адекватных размеров и батарейки, которых должно хватать на несколько дней.
    Лучше подключать Pi через Power over Ethernet с водонепроницаемым корпусом. Вот список необходимых деталей.


  • Существует ли коробочное решение — образ или ISO?
    Можно найти полный образ на SD-карте на сайте FlightAware, но если вы будете строить систему из модульных компонентов, то у вас будет преимущество перед любым другим софтом, разработанным под dump1090.


  • Будет ли детальный обзор на какое-нибудь оборудование?
    Ждите следующего поста о результатах, которые я получил при помощи разных антенн и тюнеров.

antennas


Изображение: тестирую антенны — антенна из банки, FlightAware, 2x 1090 MHz.


Дополнительные материалы


Также вам могут понравиться следующие блоги и статьи о том, что можно сделать с помощью Raspberry Pi и Docker:


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334360/


Метки:  

[Из песочницы] Как сдают ISTQB® Foundation Level на русском: шпаргалка по сертификации тестировщика

Пятница, 28 Июля 2017 г. 18:47 + в цитатник
На написание данной статьи подтолкнуло не столько недавнее получение заветного статуса ISTQB Certified Tester, сколько собирание по крупицам материалов для подготовки к экзамену. Например, последняя статья на Хабре по этой теме была в 2012 году. Плюс большинство материалов подразумевает проведение экзамена на английском, а я предпочел сдавать на русском (как оказалось в дальнейшем, в один день со мной сдающих на английском не оказалось вовсе).

И хотя в сети существует устоявшееся мнение, что пробных экзаменов на русском языке нет, это не соответствует действительности. Поэтому если вы готовитесь к экзамену ISTQB Foundation Level на русском — добро пожаловать под кат.

Немного лирики


Для начала пара слов о самой сертификации. Как говорит Википедия, система зародилась в Шотландии (Эдинбург) в 2002 году. Цель появления — стандартизировать знания и умения тестировщиков. Сейчас сертификат признается в 56 странах.

Система трехуровневая, отсчет идет снизу — для наглядности приведу картинку.


В России для сдачи доступны экзамены 1 и 2 уровней. Стоимость единичного экзамена 150 евро, при этом экзамены 2 уровня состоят из нескольких этапов по 150 евро каждый. При этом на русском можно сдать только самый первый экзамен базового уровня, о чем мы дальше и будем говорить.

Самостоятельная подготовка


Основные материалы, используемые для самостоятельной подготовки — глоссарий и конспект. Материалов новее перевода за 2011 год в сети нет. Перед началом обучения нужно сразу дать себе моральную установку «понять и простить», т.к. многие термины дублируют друг друга по смыслу, но не написанию. Особенно этим грешит глоссарий, выдавая строки формата «А — см. Б». Здесь важно сразу понять, что профессиональный опыт тестировщика (если он имеется) не особо поможет в процессе сдачи экзамена, поэтому лучше скрепя сердце запомнить логику и определения в том виде, в котором они даются в материалах — вопросы будут строги и беспощадны.

После длительного (или не очень) изучения этих двух книжек возникает логичный вопрос — а где можно «пощупать» сами вопросы? И тут вылезает интересный факт — сейчас ISTQB находится в ведении Global Association for Software Quality (GASQ). Именно в эту организацию отправляются все ваши данные при регистрации и именно она в дальнейшем будет направлять вам письма (но об этом позднее). Так вот, на сайте GASQ есть замечательный раздел пробных экзаменов, где с легкостью можно пройти экзамен на русском.
Но не обошлось без нюансов:

1. Для возможности зарегистрироваться у вас в браузере нужно разрешить данному сайту открывать всплывающие окна — лиц. соглашение с кнопкой, переводящей на форму регистрации, выводится строго во всплывающем окне. Без этого корректирования настроек браузера вы сможете лишь с грустью созерцать мигающую страничку.

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

Из хороших новостей — сейчас «боевой» экзамен сдается на компьютерах, поэтому пройти пробник полезно хотя бы для ознакомления с интерфейсом — он идентичен для обоих вариантов.

Итак, вы прошли пробный экзамен, набрали какие-то проценты — как понять, где ошиблись и в чем эти ошибки заключались? Ведь форма результатов выдает только раздел, в котором было правильно отвечено Х из Y вопросов.



И тут нам на помощь приходит страничка разбора ответов на русском от Белорусской Национальной коллегии тестировщиков! Важность их текста невозможно переоценить, т.к. аналогичные результаты в отношении вашего «боевого» экзамена GASQ предлагает получить вам за 60 евро. Кстати, внимательный тестировщик заметит, что вопросы в пробном экзамене и вопросы в разборе ответов совпадают, может отличаться лишь нумерация ответов.

Непосредственно экзамен


Книги вызубрены, пробный экзамен решается на 95-100%, кандидат готов к бою — что дальше?
Для начала регистрируемся на экзамен в интересующую вас дату в нужном городе. Настоятельно рекомендую делать это напрямую в GASQ, т.к. линк с сайта RSTQB (официальный представитель сертификации в РФ) все равно ведет в форму GASQ. Во время регистрации лучше не указывать ничего в поле «Company» — иначе вас по умолчанию считают сотрудником и выставят оплату по счету в банке. Оставляем поле пустым, метод оплаты выбираем «Credit card». О самом факте оплаты будет чуть ниже.

После регистрации вам напишет обворожительная (надеюсь) девушка из GASQ с подтверждением брони и предупредит, что в случае подтверждения экзамена на указанную дату будет отдельное письмо. Позволю себе остановиться тут подробнее: да, регистрация на конкретную дату еще не означает, что экзамен будет 100% — возможен недобор или иные форс-мажорные обстоятельства. В этом случае будет перенос экзамена на ближайшую дату, о чем вас уведомят письмом. Далее, за 8-10 дней до экзамена ваша выбранная дата исчезает из списков регистрации — это всего лишь означает, что регистрацию закрыли (опять же, если вы откладывали регистрацию на последний момент и «пролетели», у вас еще есть шанс — мой коллега, опоздав с регистрацией через форму, решил вопрос письмом на контактный адрес GASQ).

Письмо с подтверждением экзамена обычно приходит за 6-7 дней до экзамена. В нем указывается дата, время и адрес проведения экзамена. Обычно это либо офис IT-компании, либо офис тренинг-центра.

Почему я до сих пор не коснулся оплаты экзамена? Дело в том, что инвойс приходит вам ровно за 24 часа до экзамена. В случае выбора метода оплаты карточкой будет два письма — инвойс в виде pdf-документа и отдельно ссылка на форму для оплаты картой (у меня письмо с payment url упало в спам, поэтому учтите этот момент). Здесь же, если вы случайно зарегистрировались как представитель компании и понимаете, что 24 часов не хватит на оплату через отделение банка, вы можете попросить перевыставить вам инвойс на оплату картой — девушки в GASQ отзывчивы и оперативны.

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

Наконец, все организационные и транспортные вопросы закрыты, материалы повторены, тесты прорешены и вы стоите перед дверью в кабинет. Как я уже упоминал выше, экзамен сдается на компьютере. Т.к. мы выбрали сдачу экзамена на родном языке, его длительность составит 60 минут (для неродного языка дается доп. время). Администратор проверит ваше ФИО по спискам (с собой нужен паспорт или водительское удостоверение) и выдаст листочек с логином/паролем. Логинитесь, соглашаетесь с лицензионным соглашением, вводите данные (желательно корректные, они потом будут напечатаны на сертификате). Теперь можно приступать, благо интерфейс вы уже детально изучили во время подготовки.

Во время экзамена пользоваться ничем нельзя. Допустимый максимум — на чистом листе бумаги // листе с логином/паролем прорешивать задачки. Главное, что нужно перебороть — начальную панику от вопросов. Как верно упоминается во всех статьях по ISTQB, пробные вопросы и реальный экзамен — как арифметика и математический анализ. Из собственного опыта — много вопросов на определение граничных значений в интервале 0<х<100 с различными вариациями; много вопросов и задач на покрытие тестами операторов кода; есть сложные вопросы по статическим методам тестирования (сложные потому, что правильно запомнить отличия между инспекцией, техническим анализом и сквозным контролем с первого раза весьма затруднительно). Попадаются вопросы с 98% совпадающим текстом, но они не одинаковые и это не баг экзамена — внимательно читайте, там обязательно есть ключевое отличие в постановке вопроса.

Таймер экзамена стартует автоматически при открытии 1 вопроса. Решать вопросы можно в любом порядке. Если закончили, пока таймер еще идет и уверены в себе — экзамен можно завершить кнопкой «End». По окончании результат будет сразу отображен на экране, как это было в пробном экзамене. В случае положительного результата через 5-6 дней придет письмо об успешной сдаче экзамена, еще через 7-10 дней сам сертификат в виде pdf-документа.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334358/


Метки:  

Почему Vue.js — лучший фреймворк для front-end разработки на 2017 год

Пятница, 28 Июля 2017 г. 17:27 + в цитатник
Как говорил М.Т. Калашников: «Просто» сделать в 1000 раз сложнее, чем «сложно». Веб-индустрии понадобилось более половины десятилетия, чтобы прийти от фреймворков-монстров к простой и элегантной конструкции. В IT простота это не только сэкономленные часы работы, а ещё и прозрачная архитектура, выливающаяся в понятный код, меньшее число багов, более быстрое внесение изменений и много других приятных вещей.

В этой статье я проведу сравнение Vue.js с двумя наиболее популярными на данный момент фреймворками: Angular и React. Vue.js намного моложе, поэтому разговор будет прежде всего о нём, об Angular и React грамотные разработчики и так знают. Я бы не начинал этот разговор, если бы Vue не предлагал чего-то действительно стоящего. К счастью это так, и я утверждаю, что в большинстве случаев Vue.js может серьёзно снизить сложность ваших программ, сделать код более лаконичным и выразительным, а отладку — короче и проще. Подробности под катом. Поехали!

Если совсем кратко, то Vue.js — невероятно ненавязчивый фреймворк. Если Angular и React заставляют вас установить целый зоопарк зависимостей, то Vue в минимальной конфигурации не просит от вас абсолютно ничего, кроме собственного js-файла. За это он даёт custom controls, data binding, кастомные директивы и, фактически, все востребованные фишки основных фреймворков. Пример ненавязчивости:

Как выглядит простейшая программа на Vue


Достаточно просто подключить библиотеку, создать контейнер и вызвать конструктор, всё как в старом добром Angular 1, только без его тормозов:

{{ message }}

Это действительно весь код, который вам нужен, это не шутка. Вы можете прямо сейчас скопировать его в редактор, сохранить как something.html и он будет работать. Без плясок с бубном, dependency hell и прочих артефактов современности. Не буду рассказывать как то же самое делается в React или Angular 2+. Про то, как вытащить JSX из React или как писать без TypeScript на Angular 2+ можно написать целую статью.

Почему бы не оставить всё как есть
Чем плох TypeScript? Хотя бы тем, что я его не заказывал. В 2005-м году мы боролись за каждый килобайт веса страницы, а сейчас сайты весят по 15 мегабайт и, как будто бы, так и нужно, но это неуважение к пользователю. Я не говорю, что в этом виноват TypeScript, или JSX, или 100500 других побочных технологий, но я хочу сам выбирать, что использовать, а что нет. И чтобы не пришлось платить за этот выбор часами на stackoverflow.

Что касается конкатенации и минификации кода, то для Vue доступно много решений с готовыми сборщиками на том же yeomen (например github.com/birdgg/generator-vuejs), так же как и для React или Angular. Разница в том, что у вас есть право выбора, использовать их, не использовать, или самому создать сборщик под особенности конкретного проекта.

Custom Controls


Распространённый сценарий развития большинства веб-приложений — увеличение плотности функционала:

  • у вас была обычная кнопка, а стала кнопка со индикатором состояния запроса
  • была обычная таблица, а стала таблица с сортировкой и фильтрами
  • было обычное меню, а стало меню с многократной вложенностью

Если такие компоненты встречаются в приложении один раз — ничего страшного, но чаще бывает, что они раскиданы по разным страницам и в большом количестве. Без custom control такие задачи решаются через боль, мучения и большие затраты времени, с custom controls это делается быстрее в несколько раз. Если вы не сталкивались с такой проблемой — значит у вас не было более-менее серьёзных проектов. Custom controls — это абсолютно must have в современном frontend-программировании. В Angular 1 custom controls отсутствовали (если не считать директивы, которые изначально предназначались совсем для других вещей). В Angular 2+ и React они есть, но достаются довольно дорого. Синтаксис Vue.js очень похож на Angular 2+, но без его ограничений. Немного модифицируем код, представленный выше:


Получилось чуть подлиннее, но у нас здесь custom controls. Custom controls в 20 строчках кода, Карл! При этом сам компонент занял всего 4 строчки. Что это значит на практике: что вы можете делить свой код на компоненты настолько мелко, насколько вам хочется, с минимальными издержками. Если в React создание отдельного компонента — целая история, в завязкой, кульминацией и развязкой, то в Vue это просто несколько секунд. И дело не в этих секундах, а в том, что с большим количеством компонентов у вас будут слабее зависимости и меньше багов.

Это синтетический пример компонента, но в реальных Vue.js раскрывает себя ещё лучше. Мы можем, например:

  • вынести весь код компонента в отдельный *.vue файл, включая html, css и javascript
  • использовать css-препроцессоры прямо в коде файле компонента, просто указав lang=«scss» или другое
  • использовать любые глобальные объекты или получать объекты через import (в React, кажется, на это есть ограничения)
  • использовать компоненты только внутри других определённых компонентов, без объявления в глобальной области видимости. Использовать компонент под другим именем, без изменения самого компонента (удобно в случае коллизии имён сторонних компонентов)

и многое другое. Для большинства этих функций нужно подключать сборщик (в документации описан webpack), однако вам дают выбор, использовать Vue на 10%, 50% или на все 100%. Плюс, на мой взгляд, они выбрали самый стабильный и прозрачный сборщик из существующих, но вы можете поменять и его. Вообще Vue поражает своей модульностью и слабосвязанностью, архитектура просто очень хорошо продуманна, что выливается в огромное удовольствие при работе с любой его составляющей. Например:

Создание своих плагинов


Перед тем, как открыть спойлер с кодом остановитесь на минутку и подумайте, как бы вы пропатчили незнакомую библиотеку, если бы захотели добавить туда новый кастомный метод. Подумали? Теперь открывайте ответ:

Как это делается в Vue.js
  Vue.prototype.$myMethod = function (methodOptions) {
    // something logic ...
  }

Vue.prototype, Карл! Вам даже не нужно знать документацию, вы её и так знаете большую её часть на уровне подкорки. Больше никаких странных конфигов, магических свойств, которые нужно указать, чтобы всё заработало. Просто Vue.prototype и имя вашего метода, почему все фреймворки не используют это? Если хотите устанавливать плагин через Vue.use(MyPlugin), то нужно определить метод MyPlugin.install, но это, как и многое в Vue, по вашему желанию.

Общая обстановка


У меня есть большие претензии к команде Angular. Даже не побоюсь сказать, что они фактически убили Angular, создав два совершенно разных продукта и назвав их одним именем. Даже у Vue больше общего с Angular и 1 и 2, чем у этих версий между собой. Возникла огромная путаница в документации, которая ещё не скоро прекратится. Но дело даже не в этом, как гласит один из канонических принципов создания хорошего ПО: делайте программы открытыми для дополнения, и закрытыми для изменения. Подобные радикальные изменения API Angular говорят о том, что продукт изначально был создан проблемным, идеальные программы не нуждаются в изменениях (например /bin/true в linux не переписывалась с 1984 года :)). Конечно Angular это не /bin/true, но реформы — всегда признак проблем.

В чём же причина? Я думаю в том, что как React — это проект для внутренних нужд Facebook, так и Angular 2+ — это проект для внутренних нужд Google. Конкретной компании не требуется поддерживать универсальность. Зачем поддерживать ES6, если в самой компании пишут на TypeScript? Зачем отделять React от зависимостей, если внутри компании он без зависимостей не используется? Конечно пользователи просят, и иногда им идут на встречу, чтобы они совсем не отвернулись, но всё же главная задача этих проектов — не наше с вами счастье, а облегчение найма в эти компании, когда приходит новичёк и уже знает основной стек технологий. Но стек конкретной компании, пусть даже очень крутой, не может являться стандартом для всей отрасли. Отсюда все проблемы с Agular и React. Vue, насколько мне известно, напротив, создавался именно для сообщества, поэтому получился модульным, универсальным, легко адаптируемым под нужные задачи.
Ваше отношение к Vue.js

Проголосовало 142 человека. Воздержалось 37 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/333004/


Метки:  

[Из песочницы] Реализация выдвижного меню NavigationDrawer при помощи DrawerLayout, с использованием произвольной разметки

Пятница, 28 Июля 2017 г. 16:37 + в цитатник
На днях, для одного из разрабатываемого нашей командой приложения, заказчик внес правку в дизайн, которая требовала разработать выдвижное меню с довольно не стандартным расположением view компонентов. Хотя на данный момент и существуют различные виды реализации данной задачи, они оказывались либо слишком объемными, либо не предоставляли реализацию нужного функционала.

Обдумав некоторое время данную задачу, я решил реализовать данное меню на основе стандартного компонента DrawerLayout, в основу которого было вложено 2 root элемента — RelativeLayout для основной разметки окна, а также еще один RelativeLayout как контейнер для бокового меню. Хотелось бы добавить, что именно 2 root элемента должно быть внутри DrawerLayout, подробнее об этом контейнере можно прочесть в официальной документации гугла.

Реализация


Xml файл разметки для основной activity






    

       
     
    

    
    
        android:clickable="true"
        android:background="#FFFFFF"
        xmlns:android="http://schemas.android.com/apk/res/android" />


Разметка основной activity готова, теперь приступим к написанию класса, который будет выполнять основную логику. Создадим класс, наследующий RelativeLayout. Данный класс реализует всю логику нашего меню, в том числе устанавливает разметку и определяет все view.

public class NavigationLayout extends RelativeLayout
{
    Button ok;
    public NavigationLayout(Context context,RelativeLayout parent)
    {
        super(context);
        initView(context,parent);
    }

    public void initView(final Context context,RelativeLayout parent)
    {
        // надуваем любой xml файл разметки
        View view= LayoutInflater.from(context).inflate(R.layout.view_drawer_layout,parent,true);

        ok=(Button)view.findViewById(R.id.ok);

        ok.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context,"Ok",Toast.LENGTH_SHORT).show();
            }
        });


    }
}

В конструктор следует передать context и parent.

parent — RelativeLayout, который был объявлен в разметке для основной activity ( )

Далее функция initView(final Context context,RelativeLayout parent) — надувает основную разметку, которая будет помещена в выдвижное меню, а также определим тут все view компоненты и их слушатели.

В R.layout.view_drawer_layout для примера я объявил всего одну кнопку.




    


На данном этапе основная часть готова, осталось лишь добавить наш NavigationLayout при помощи addView к основному parent контейнеру.

Создадим класс, наследующий AppCompactActivity

public class ParentNavigationActivity extends AppCompatActivity {
    NavigationLayout navigationLayout;
    RelativeLayout left_drawer;

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);
        setupMenu();
    }

    public void setupMenu()
    {
        left_drawer=(RelativeLayout) findViewById(R.id.left_drawer);
        navigationLayout=new NavigationLayout(getApplicationContext(),left_drawer);

        left_drawer.addView(navigationLayout);
    }
}

Данный класс переопределяет стандартный метод setContentView, добавляя в него вызов функции, которая 'инициализирует' выдвижное меню. Также здесь мы создаем объект ранее написанного нами NavigationLayout класса и добавляем его при помощи left_drawer.addView(navigationLayout) к родителю, который и является контейнером бокового меню.

Осталось дело за малым — чтобы все заработало, нужно лишь создать экран (activity) и унаследовать ParentNavigationActivity, который мы только что создали.

public class MainActivity extends ParentNavigationActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test); 
    }

}

Таким образом, при наследовании ParentNavigationActivity и вызове функции setContentView, в нашей activity появляется готовое меню.

Хотелось бы добавить, что 2 контейнера, лежащих в основе DrawerLayout, необязательно должны быть RelativeLayout. Вместо них можно использовать constraintlayout, framelayout, linearlayout и другие.

На данном этапе разработка выдвижного меню завершена!


Данный способ является довольно простым в реализации, а также гибким в плане добавления меню к любым activity. Надеюсь что данная статья поможет android разработчикам упростить создание бокового меню для своих приложений.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334350/


[Из песочницы] Как уважать время или как стать эффективным тим лидером

Пятница, 28 Июля 2017 г. 15:30 + в цитатник
image alt


Нужно ли управлять временем?


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

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

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

Скорей всего некоторые из вас неосознанно применяют некоторые принципы на практике в каком либо объеме, или уже начали использовать инструменты для управления временем. Но то что казалось бы так очевидно, на самом деле не так уж и просто.

Давайте разберемся с терминами и инструментами


Время можно ощущать на себе только когда вы ставите некие точки отсчета, и когда оно измеряется отрезками.

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

Вторым таким термином будет бюджетирование времени, т.е. выделение отрезка времени на выполнение какой-либо задачи.

Дэвид Аллен является пионером в области тайм менеджмента, и он в своей книге “Getting things done” ввёл одноименный термин GTD (доводи свои задачи до конца).

Основным тезисом этой книги является то, что все поступающие к вам дела нужно регистрировать, все – это значит все без остатка. Выполнять задачи можно позже, но регистрировать их нужно сразу как они появились. После того как у вас образовалась «свалка» таких задач, необходимо начать их решать.

image alt

Для этого нужно сделать следующие шаги



  • Выбери. Необходимо определить всё, что вы должны сделать.
  • Проанализируй. Для каждой задачи необходимо определить какой будет следующий шаг. Если на выполнение задачи требуется не более пары минут – то лучше сделать сразу. Для более продолжительных задач необходимо определить адекватное время решения этой задачи, либо делегировать ее, если это возможно.
  • Организуй. Все важные встречи необходимо фиксировать в календаре. Все остальные задачи перенесите в список задач на будущее. Наименее срочные задачи нужно хранить в списке «когда-нибудь сделаю».
  • Проводи ревью. Ежедневно нужно просматривать список задач и календарь. Еженедельно нужно просматривать список проектов, будущих дел и делегированных задач.
  • Сделай. Выполните задачу учитывая её время, важность, а также затраченную энергию.
  • Отдохни. Всё, что не было сделано – всплывет на следующем ревью.

И теперь хочется перейти к инструментам регистрации задач. Самое главное, что нужно запомнить – голова не является таким инструментом. И на данный момент на рынке представлено множество предложений таск менеджеров и календарей (не буду ничего рекламировать), каждый может для себя решить сам, на крайний случай можно пользоваться ежедневником.

Одним из инструментов определения типа задач — является матрица Эйзенхауэра


А) Срочные и важные дела. Это неотложные проблемы, критические ситуации и т.п. Если здесь начали появляться задачи, это скорее всего значит, что вы в других квадрантах что-то не доглядели. Ситуацию упустили из-под контроля, либо из-за лени, либо из-за недальновидности. Естественно если постоянно решать подобные задачи, можно очень быстро перегореть. И всё ваше свободное время будет занимать тактические задачи, а над стратегией уже не будет времени подумать.

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

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

Г) Несрочные и неважные дела. Это задачи без пользы и заниматься нужно ими в последнюю очередь, но мы занимаемся ими в первую очередь. Это то, что нас отвлекает, приятные активности, их ещё называют пожирателями времени. Сюда можно отнести соц. сети, веб-серфинг и тому подобное.
Вывод напрашивается сам собой, держать себя нужно в квадранте Б и как можно меньше времени уделять квадранту Г.

Чтобы так было всегда необходимо использовать определенный инструмент – система принятия решений.

Есть два параметра времязатратность (Т) и энергозатратность (Е), каждый из них оценивается по 10 бальной шкале и считается так Т+Е/2 и получаем затраты на решение нашей задачи.

Следом к ним добавляется ещё два параметра: результаты сейчас (R1) – это всё, то полезное, что приносит профит уже сейчас и потенциально-прогнозируемый результат (R2) – это всё то, в чём мы видим перспективность задачи, также оцениваются по 10-бальной шкале и считается так R1+R2/2 и получаем результативность нашей задачи. И чтобы получить ценность нашей задачи мы результаты делим на затраты.

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

Дальше хочу акцентировать внимание на принципе Парето (20/80)


image alt


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

Делайте в первую очередь те задачи результативность которых самая большая


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

И конечно нужно упомянуть Брайана Трейси, с его принципом лягушки


image alt

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

Следующий принцип, введенный специалистами — это принцип поедания слона


image alt

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

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

Далее хочется рассказать о том, что важным принципом является — умение говорить вежливое “нет”


image alt

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

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

Ну и когда мы говорим об управлении временем, то необходимо упомянуть о том, кто ворует наше время.

Поговорим о пожирателях нашего времени





Дэн Кеннеди назвал их вампирами и установил иерархию для них.

  • Самый коварный из них вампир-минутка, т.е. это незначительные просьбы вроде бы вам ничего не стоящие, но ворующие у вас драгоценное время. Конечно в работе скажем HelpDesk невозможно отложить срочные задачи, но в личной жизни нужно присмотреться к подобным проблемам.

  • Следом идёт вампир-ерунда, его цель сбить вас с толку и отвлечь от существенных задач.

Бороться с ним необходимо взвесив для себя, приведет ли эта задача вас к чему-либо.

  • Вампир-дверь открыта, это когда к вам приходят коллеги из разных отделов, которые отвлекают вас, они могут украсть у вас очень много времени.

  • Вампир-телефон, это постоянно отвлекающие вас звонки, уведомления и тому подобное.

Хороший способ с ним бороться, естественно отключить его, когда нужно сосредоточиться на важной задаче.

  • Вампир-непунктуальность, нужно требовать от других людей уважения к своему времени.

  • Вампир-толпа, это значит следовать окружающим и делать как делают они. Нужно избегать этого, стараться не поддаваться этому и следовать своему расписанию.

  • Вампир-бесцельность, дела, которые делаются без цели.

  • Вампир-нытик, это оправдание своим неудачам.

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

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

И одной из таких эффективных систем является Кайдзен, она учит увеличивать количество эффективного времени и учит организовывать своё рабочее пространство.

На русском языке она звучит как 5С:


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

К примеру инженеру ЦОДа необходимо установить новый сервер или заменить существующий, он берет с собой сервер, берет к нему салазки, когда приходит до стойки выясняется что он забыл ключ, кладет сервер, салазки, возвращается за ключом, взял ключ, открыл стойку, демонтирует старый сервер, ставит салазки для нового, уже уставший начинает монтировать сервер и выясняется что эти салазки к нему не подходят.
Из за казалось бы ерунды, было потрачено существенное количество времени.

И еще, скажем эникейщику нужно установить программу пользователю, он идет через весь офис, вставляет флешку в компьютер, судорожно ищет нужную программу в папках “новая папка”,”новая папка (2)”,”123”,”qwerty”. Открывает папку “distrib” она оказывается пустой, он вынимает флэшку, бежит к своей тумбочке за другой флэшкой, сделав десять шагов он понимает что отдал флешку Пете, который сегодня заболел. И понимает что нужную программу теперь можно только скачать, и он возвращается на свое рабочее место, по дороге другой пользователь озадачивает его другой проблемой, и это можно продолжать до бесконечности. В итоге человек весь день работал, но все остались не довольны, в том числе и он сам.

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

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

Теперь разберём методы, которыми можно и нужно заставлять себя выполнять те или иные задачи


image alt

Есть интересный метод «принцип помидора» — для выполнение какой-либо задачи, необходимо взять 25 минутный промежуток времени в который не предполагается отвлекаться от поставленной задачи, потом берёте небольшой перерыв, опять 25 минут, потом опять небольшой перерыв и таким образом вы распиливаете дела, которые необходимо выполнить.

Следующий метод – пирог времени, его суть в классификации рабочего времени, ведь не секрет, что большая часть наших дел практически однообразна и ежедневна. Так вот, можно начать вести тайм-трекер наших задач, целью его будет определить на что тратится наше время и в дальнейшем оптимизировать его и выяснить может вы тратите время на лишние задачи или вам не свойственные, где можно разгрузить себя и от чего отказаться.
Очень полезная вещь для новичков в компании, либо наоборот для особо загруженных ребят.

Следующий наш шаг – это инструменты


  • Якорь – это подготовка к выполнению задачи, и желательно себя подготавливать бессознательно.
  • Заточить карандаш – это подготовка инструментов таким образом, чтобы не отвлекаться на их поиск, чтобы они все были под рукой.
  • Продырявьте сыр – любую задачу нужно выполнять по небольшим «укусам», либо шагам.
  • Вознаградите себя – в конце необходимо себя наградить, естественно награда должна быть адекватна задаче.

И немного о неопределенных задачах


Работа в неопределенных условиях – когда задача до конца нам не понятна, но за нее необходимо браться и в дальнейшем мы получаем какие-либо дополнения или уточнения для ее выполнения и не всё будет известно заранее.

Такого рода задачи характерные для руководителей проектов, и в принципе для высокого менеджмента. И для выполнения такого рода задач необходимо корректировать свой первоначальный план при получении новых деталей , не нужно думать если к вам поступила не определённая задача, то и план для ее решения будет неопределённый и корректировать его не нужно.

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

Ну и необходимо подвести обобщение, чтобы выполнять сваливающиеся на нас задачи


Главное то, что необходимо составить правильный режим дня и знать свои слабые и сильные стороны, всё необходимо делать планомерно даже небольшими шагами. И даже трудное дело станет для вас привычным, а в итоге может даже и приятным. А знание себя очень помогает в принятии разного рода решений.

На начальном этапе нужно уделять особое внимание пожирателям времени, и необходимо культивировать в себе полезные привычки. Награды и наказания, публичные обещания – нужны для мотивации, чтобы выполнять разного рода задачи


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

image alt

Литература используемая в статье:

— Келли Макгонигал “Сила воли”
— Дэн Кеннеди “Жёсткий тайм-менеджмент”
— Брайана Трейси “Съешьте лягушку! 21 способ научиться успевать”
— Дэвид Аллен “Как разобраться с делами”
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334348/


Метки:  

Геймджем для Lua-разработчиков на движках Corona и Defold

Пятница, 28 Июля 2017 г. 14:43 + в цитатник

Партнеры и друзья Appodeal, Corona Labs совместно с Defold и DevGAMM Минск, объявляют о старте геймджема #CoronaDefoldJam на базе Lua. Джем пройдет с 28 июля по 30 сентября 2017 на платформе itch.io. Требование к участникам только одно — игры в рамках джема должны быть созданы на Corona или Defold. Если вы никогда не использовали эти движки, не страшно: обе платформы просты для изучения и обладают очень дружелюбными сообществами, которые всегда помогут разобраться. В общем, #CoronaDefoldJam — идеальный повод освоить новые инструменты для создания игр; тем более, что джем поддерживает легендарный Джон Ромеро.



Правила джема разрешают использовать готовые архивы (например, вот этот), однако игра должна быть создана специально для #CoronaDefoldJam. Еще из хороших новостей — джем стартует вместе с Ludum Dare 39 и будет иметь с ним общую тему. Она появится на странице джема 28-29 июля. Itch.io позволит продвигать игры в широком международном кругу разработчиков и любителей indie.
Джем — отличная возможность наконец взяться за разработку игры, о которой вы давно думали. К тому же, организаторы обещают призы:


  • 10 000 установок от Corona с рекламной кампанией в 25 000+ приложениях по всему миру для лучшей игры на Corona;
  • Для всех победителей — возможность выставляться с созданной игрой на DevGAMM Минск (16-17 ноября 2017), где и состоится церемония награждения;
  • Wacom Intuous Pro за лучший арт на Corona;
  • Шведские наушники JAYS ручной сборки за лучшую игру на Defold;
  • Три Amazon Echo Dot за лучшие технологии на Defold;
  • Кредиты для Steam или itch.io на выбор + лицензии Spine ESS.

Подробнее с условиями можно ознакомиться по ссылке.


Все вопросы вы можете задать организаторам через почту: oleg@gamesjam.org, в твиттере с хэштегом #CoronaDefoldJam или в секции “коммьюнити” на itch.io.


Slack Defold
Slack Corona

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334344/


Как «Актив» организовал «электронную переговорку»

Пятница, 28 Июля 2017 г. 14:36 + в цитатник

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


Но это только половина проблемы. Как всем известно, ресурсами еще нужно уметь грамотно управлять, чтобы не случалось коллизий. Ситуации, когда во время встречи с партнерами, в переговорную врывается руководитель соседнего подразделения со словами “И эта занята!?”, недопустимы.



Второй момент – когда под рукой нет инструмента (к примеру, Outlook или его web-интерфейса), чтобы забронировать переговорную комнату, но очень нужно «успеть» захватить ценный ресурс. Для осуществления задуманного, необходимо идти на свое рабочее место и с него осуществлять бронирование. Теперь представим, что у вас нет на это времени, выходя из переговорной комнаты с очередной встречи.


Можно конечно придумать еще различные варианты «почему». Для нас уже этих двух моментов было достаточно, чтобы начать исследования в направлении поиска решения проблемы.


Как мы дошли до собственного решения


Изначально рассматривались стандартные два варианта:

  • Найти что-то готовое;
  • Реализовать самостоятельно.

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


Мы выделили несколько решений, которые рассматривали как потенциальные для внедрения:


Посмотрев на каждое, проанализировав их функциональность и конечную стоимость, мы решили разработать свой продукт. И не потому, что нас не устроила функциональность. Нас больше не устроила стоимость и невозможность кастомизировать решение под определенные требования.
Было понятно, что нам нужно, мы уже имели перед глазами готовые продукты, следовательно, оставалось только начать «творить”.


Основные задачи, решаемые нашим продуктом


Мы выделили основные задачи, которые должен был первично решать продукт:

  • Простота администрирования;
  • Индикация статуса переговорной комнаты;
  • Возможность быстрого и удобного бронирования переговорной комнаты;
  • Просмотр расписания бронирований переговорной комнаты;
  • Интеграция с MS Exchange.

Реализация


После проработки задания, макетов интерфейсов и отрисовки необходимой графики, мы приступили к разработке. Нужно оговориться, что для конечного продукта требовалась не только разработка. Необходимо было еще выбрать аппаратную часть. Естественно, мы сразу решили, что конечным устройством у нас будет планшет. Изучив цены и характеристики предлагаемых на рынке планшетов, мы остановили выбор на Lenovo TAB2 A10-30 10.1. По соотношению цена/качество он нас более чем устроил. При этом нужно понимать, что можно на самом деле использовать любое другое устройство, которое устроит по своим техническим, ценовым, имиджевым и другим параметрам. Но и это еще не все. Планшеты нужно еще как-то крепить около переговорных комнат. Мы знали, что для этого используются специализированные кейсы и начали поиск на просторах интернета. Как оказалось, найти подходящий кейс не просто. Не так много предложений есть на рынке, и из имеющихся не так много тех, которые бы могли нам подойти по своему виду. Но как говорится, “вода камень точит”. Кейсы были найдены, планшеты закуплены, разработан продукт, который удовлетворял всем вышеуказанным требованиям.


Что получилось


Немного об архитектуре решения


  • Клиентская часть представляет из себя web-приложение, реализованное с использованием AngularJS. Мы не стали реализовывать нативный клиент под устройства, хотя рассматривали такой вариант и, если будет продолжение в серьезном развитии продукта, то есть большая вероятность такой разработки.
  • На текущий момент мы используем вспомогательный продукт Kiosk Mode Browser, позволяющий заблокировать переход в любые другие приложения из режима запущенного браузера, а также «залочить» возможность перехода по любым адресам. С функциональностью данного продукта вы можете ознакомиться по ссылке.
  • Бэкенд реализован на языке C# с использованием фрэймворка ASP.NET Core. В данном случае мы не привязаны к платформе, на которой можно развернуть бэкенд. На текущий момент у нас он крутится на Windows Server, но ничто не мешает его развернуть на linux/unix – машинах.
  • В качестве СУБД мы используем MS SQL. При этом в наших разработках используется ORM Entity Framework, что позволяет безболезненно переключиться практически на любую sql-ориентированную СУБД.

    Саму базу данных на текущем этапе мы используем в очень ограниченном формате. В ней мы храним аккаунт администратора и параметры переговорных комнат. Основным источником данных о расписаниях, списке переговорных комнатах у нас является MS Exchange Server. В дальнейшем за счет реализации промежуточного слоя между Exchange и бэкендом роль БД будет расширяться.

  • MS Exchange Server, с которым посредством его API взаимодействует наш сервер приложения.

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


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


Интерфейс


Админка


Работа с конечным устройством (планшетом) начинается с привязки к конкретной переговорной комнате. Для этого реализована простая «админка», в которой выводится список с переговорными комнатами, имеющимися в компании.



Привязка осуществляется выбором одной из переговорок в данном списке и вводом административного пароля. На этом настройка заканчивается и можно монтировать планшет на стену.


Дополнительной функциональностью является возможность задать параметры переговорной комнаты, такие как:

  • Количество человек, которое вмещает переговорная комната для комфортного размещения;
  • Наличие оборудования для конференцсвязи;
  • Наличие компьютера;
  • Наличие канцелярии;
  • Наличие доски;
  • Наличие телевизора.



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


Основной экран


На основном экране представлено название переговорной комнаты, индикация состояния занятости, текущие дата и время. С основного экрана можно перейти в просмотр расписания и бронирования переговорной комнаты, а также просмотреть детальную информацию по переговорке.


На текущий момент мы определили 3 важных статуса занятости переговорной комнаты:


  1. Переговорная комната свободна;
  2. Переговорная комната свободна еще <= 15;
  3. Переговорная комната занята.

Переговорная свободна Переговорная скоро будет занята Переговорная занята

Если назначение первого и третьего статусов должно быть интуитивно понятно, то второй требует небольших комментариев. Данный статус мы реализовали для того, чтобы у сотрудника была возможность воспользоваться переговорной комнатой прямо сейчас, но предупредить, что у него в распоряжении не более 15 минут (к примеру нужно совершить важный звонок, что бы вокруг не было “фона”).


Бронирование


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



Мы хотели максимально ускорить и упростить данный процесс, поэтому не стали перегружать интерфейс необходимостью выбора организатора и участников встречи, а также вводом темы (хотя сделать это при необходимости совсем не сложно). В большинстве случаев, проблема с доступностью переговорных комнат ощущается в день ее внезапной надобности. Поэтому мы пошли по пути упрощения — выбрать можно только время начала и продолжительность встречи. Дата всегда считается текущей.



При этом начиная выбирать время начала встречи, у вас будут активироваться или деактивироваться элементы с выбором продолжительности встречи. Логика простая – если промежуток начала и продолжительности не занят, то элемент с заданной продолжительностью становится активным, если какая-либо встреча уже попадает в заданный диапазон, элементы деактивируются.



После выбора начала встречи и ее продолжительности можно бронировать. На этом процесс завершен, вы сразу можете увидеть результат произведенных действий, перейдя в просмотр расписания бронирований.


Расписание


На экране расписания бронирований отображены списком диапазоны занятости и свободы «переговорки».



Как видно, при бронировании посредством сервиса, тема встречи задается как “Экспресс-бронирование”. При клике на не занятый диапазон, мы попадаем в режим бронирования, процесс которого описан выше.


О планах


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


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

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

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334334/


Метки:  

ICFP Contest 2017 — проверка на прочность для настоящих разработчиков

Пятница, 28 Июля 2017 г. 14:02 + в цитатник
ICFPC — ежегодное соревнование для программистов. Оно проходит в онлайне и длится 72 часа. ICFPC 2017 начнётся в пятницу 4 августа в 12:00 (UTC) и закончится в понедельник.

Я расскажу, почему нельзя пропускать ICFPC и дам серию советов. Освободи следующие выходные, собери команду и участвуй!



Соревнование для вдумчивых хакеров


ICFPC — командное соревнование. Соревнований для одиночек много: например, Facebook Hacker Cup и Google Code Jam. Если вам нравятся AI для игр, то codingame.com проводят отличные челенджы раз в 2-3 месяца. В одиночных соревнованиях топ обычно забит какими-то гениями, а в командных можно хорошо выступить за счет упорства и хорошей организации.

Команда может быть любого размера. Обычно задачи на ICFPC можно решать несколькими способами. Попробовать все способы и выбрать лучший — это большая работа. В 2011 году я играл в команде из двух человек. У нас не было недостатка идей, но мы остро чувствовали недостаток рук.

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

Задачи небанальные. Организатор соревнования меняется каждый год. Обычно это университет, поэтому они добавляют в задачи отсылки к научным проблемам и классике computer science (скажем, в 2014 была отсылка к SECD-машинам). Кроме того, ICFPC приурочен к научной конференции по функциональному программированию ICFP, и это влияет на задачи. Через раз приходится читать описания на функциональном псевдоязыке (не бойтесь, понятном для обывателей!), а потом программировать виртуальные машины и компиляторы.

Задача одна! За 72 часа команда неограниченного размера должна решить всего одну задачу. Но многогранную и трудную. Её нельзя решить оптимально, но можно решить лучше других команд. Самыми необычными и яркими задачами считаются задачи 2006 и 2007 годов, в которых балом правили виртуальные машины внутри виртуальных машин и а также реверс-инжениринг виртуальных машин.

У меня юбилей )


Я, xoposhiy, участвовал в ICFPC 9 раз. И каждый раз было что-то новенькое:

  • в 2007 была задача на редактирование ДНК пришельца и структуру данных rope string,
  • в 2009 — вывод спутников на орбиту с помощью программы для виртуальной машине симулятора,
  • в 2010 — ни на что не похожая задача про машинки и топливо,
  • в 2011 — карточная игра Lambda the Gathering про SKI-комбинаторы,
  • в 2012 — бот для Boulder Dash с изменяющимися в процессе игры требованиями,
  • в 2013 — подбор арифметической функции по примерам входов и выходов,
  • в 2014 — боты для Pac-Man на двух виртуальных машинах,
  • в 2015 — гексагональный тетрис с заклинаниями,
  • в 2016 — решение и составление трудных оригами.

В последние годы наша команда стабильно попадает в десятку лучших:

  • в 2016 — 6 место,
  • в 2015 — 7 и 13 место (было две команды),
  • в 2014 — 7 место,
  • в 2013 — 3 место,
  • в 2012 — 13 место,
  • в 2011 — не вышли в финальный раунд,
  • в 2010 — 22 место.

Интересно, что третье место в 2013 году выиграла команда из 8 человек. А в прошлом году 6 место заняла команда аж из 12 человек. Тут нормальный человек должен удивиться, как мы способны такой толпой трое суток продуктивно трудиться всего над одной задачей? Рассказываю!

Как мы боремся с мифическим человеко-месяцем


Закон Фредерика Брукса: «Если проект не укладывается в сроки, то добавление рабочей силы задержит его ещё больше»

Расскажу на примере задачи с прошлогоднего ICFPC 2016.

Дан силуэт плоского оригами, собранного из квадратного листа бумаги 1x1. Нужно восстановить развертку оригами, то есть отметить на листе линии сгибов и описать для каждой вершины на развертке, куда она переходит на силуэте. В начале есть 100 силуэтов от организаторов. Через сутки участники смогут сабмитить свои задачи для соперников.

image

Как решать?

Используйте дуальность задачи. Нужно решать оригами. А ещё нужно придумывать оригами, которые не смогут решить соперники. Это первая возможность для параллельной работы. Дуальные задачи — обычное дело в ICFPC. В 2010 и 2014 году были похожие задачи.

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

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

Потом мы заметили несколько трудных задач от команды WILD BASHKORT MAGES (привет, ripatti), которые принесли бы много баллов, и написали решатель именно для них. (В конце мы узнали, что MAGES тоже написали специализированный решатель для наших оригами)

Потом мы написали визуальный решатель, который помог справиться с несколькими десятками оригами вручную. В итоге у нас было 5 различных решателей для одной задачи.

В 2013 году мы тоже заняли третье место благодаря тому, что у нас было два разных решателя для разных типов задач. В ICFPC специализация и дублирование решений помогают.

Начните со вспомогательного кода. Перед тем, как программировать решатели, нужно закодировать структуры данных, описывающие предметную область. Запрограммировать ввод-вывод. Протестировать. Попрофайлить и оптимизировать. Пока одна группа занимается этими задачами, остальные думают над алгоритмами.

Визуализируйте. Оригами были описаны числами, но мы хотели посмотреть на них, поэтому сразу взялись за визуализатор. В каждом ICFPC нужно делать какой-нибудь визуализатор или визуальный отладчик. Вот наш:



А вот так выглядит визуализация в решателе команды-победителя Unagi:





Вложитесь в инфраструктуру. Как только начальный хаос и спешка закончатся, автоматизируйте рутинные задачи. Мы сделали автоматическое скачивание новых задачек. Сложили решенные оригами в Git, чтобы они были доступны всей команде. В других ICFPC писали систему для тестирования финального качества решения, чтобы экспериментировать и понимать, полезны наши доработки или вредны.

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

image

Поделите на два. 12 человек превращаются в 6, если работают в парах. Пара даёт более качественное решение. Пара может в любой момент разделиться, причем каждый участник будет хорошо разбираться в общем коде. Например, можно начать делать визуализатор в паре, заложить правильную архитектуру, а потом спланировать фичи и разойтись делать их параллельно. Ещё в паре веселее кодить, но это не точно.

image

Избегайте merge-конфликтов. История в репозитории большой команды получается ветвистой. При любом неаккуратном движении случаются merge-конфликты, которые портят нервы и отнимают время. Поэтому навык бережного отношения к истории изменений очень полезен на ICFPC. Договоритесь об оформлении кода, добавьте файл с настройками IDE в репозиторий, используйте автоформатирование.

Соберите команду мечты. Задача не известна заранее, её нужно будет декомпозировать «на лету». Поэтому в ICFPC полезны люди, способные быстро ориентироваться в обстановке, генерировать идеи и продавать их другим членам команды, вкладывать свои силы в самую полезную задачу, читать кучу чужого кода и не ломать его своими правками.

Организуйте научный отдел. Часть команды может читать научные статьи, искать готовые инструменты, расшифровывать подсказки от организаторов и других участников. Как любая наука, это не даёт мгновенный выхлоп. Но в прошлом году мы таким образом отыскали пару полезных мыслей.

Не забудьте выспаться. Вас ждёт 72-часовой марафон, и свежие головы будут на вес золота.

Команда kontur.ru


В этом году в нашей команде [пока] 14 человек. Мы постараемся следовать всем своим советам и показать лучшую игру.

Во время соревнования попробуем писать интересное в наш канал в Телеграме. Подписывайтесь и болейте за нас.

t.me/KonturTech

Настоящие джедаи не смогут просто наблюдать, верно? Тем более, что играть в ICFPC интересно и увлекательно вне зависимости от финального результата. Так что собирайте команду и участвуйте. И да пребудет с вами сила :)

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334324/


[Перевод] Как работает нейронный машинный перевод?

Пятница, 28 Июля 2017 г. 13:55 + в цитатник

Описание процессов машинного перевода основанного на базе правил (Rule-Based), машинного перевода на базе фраз (Phrase-Based) и нейронного перевода


image

В этой публикации нашего цикла step-by-step статей мы объясним, как работает нейронный машинный перевод и сравним его с другими методами: технологией перевода на базе правил и технологией фреймового перевода (PBMT, наиболее популярным подмножеством которого является статистический машинный перевод — SMT).

Результаты исследования, полученные Neural Machine Translation, удивительны в части того, что касается расшифровки нейросети. Создается впечатление, что сеть на самом деле «понимает» предложение, когда переводит его. В этой статье мы разберем вопрос семантического подхода, который используют нейронные сети для перевода.

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

Очень простой, но все же полезной информацией о процессе любого типа автоматического перевода является следующий треугольник, который был сформулирован французским исследователем Бернардом Вокуа (Bernard Vauquois) в 1968 году:

image

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

Левая часть треугольника характеризует исходный язык, когда как правая — целевой. Разница в уровнях внутри треугольника представляет глубину процесса анализа исходного предложения, например синтаксического или семантического. Теперь мы знаем, что не можем отдельно проводить синтаксический или семантический анализ, но теория заключается в том, что мы можем углубиться на каждом из направлений. Первая красная стрелка обозначает анализ предложения на языке оригинала. Из данного нам предложения, которое является просто последовательностью слов, мы сможем получить представление о внутренней структуре и степени возможной глубины анализа.

Например, на одном уровне мы можем определить части речи каждого слова (существительное, глагол и т.д.), а на другом — взаимодействие между ними. Например, какое именно слово или фраза является подлежащим.

Когда анализ завершен, предложение «переносится» вторым процессом с равной или меньшей глубиной анализа на целевой язык. Затем третий процесс, называемый «генерацией», формирует фактическое целевое предложение из этой интерпретации, то есть создает последовательность слов на целевом языке. Идея использования треугольника заключается в том, что чем выше (глубже) вы анализируете исходное предложение, тем проще проходит фаза переноса. В конечном итоге, если бы мы могли преобразовать исходный язык в какой-то универсальный «интерлингвизм» во время этого анализа, нам вообще не нужно было бы выполнять процедуру переноса. Понадобился бы только анализатор и генератор для каждого переводимого языка на любой другой язык (прямой перевод прим. пер.)

Эта общая идея и объясняет промежуточные этапы, когда машина переводит предложения пошагово. Что еще более важно, эта модель описывает характер действий во время перевода. Давайте проиллюстрируем, как эта идея работает для трех разных технологий, используя в качестве примера предложение «The smart mouse plays violin» (Выбранное авторами публикации предложение содержит небольшой подвох, так как слово «Smart» в английском языке, кроме самого распространенного смысла «умный», имеет по словарю в качестве прилагательного еще 17 значений, например «проворный» или «ловкий» прим. пер.)

Машинный перевод на базе правил


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

  • Процесс строго следует треугольнику Вокуа, анализ очень часто завышен, а процесс генерации сводится к минимальному;
  • Все три этапа перевода используют базу данных правил и лексических элементов, на которые распространяются эти правила;
  • Правила и лексические элементы заданы однозначно, но могут быть изменены лингвистом.

Например, внутреннее представление нашего предложения может быть следующим:

image

Тут мы видим несколько простых уровней анализа:

  • Таргеритование частей речи. Каждому слову присваивается своя «часть речи», которая является грамматической категорией.
  • Морфологический анализ: слово «plays» распознается как искажение от третьего лица и представляет форму глагола «Play».
  • Семантический анализ: некоторым словам присваивается семантическая категория. Например, «Violin» — инструмент.
  • Составной анализ: некоторые слова сгруппированы. «Smart mouse» — это существительное.
  • Анализ зависимостей: слова и фразы связаны с «ссылками», при помощи которых происходит идентификация объекта и субъекта действия основного глагола «Plays».

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

image

Применение этих правил приведет к следующей интерпретации на целевом языке перевода:

image

Тогда как правила генерации на французском будут иметь следующий вид:

  • Прилагательное, выраженное словосочетанием, следует за существительным — с несколькими перечисленными исключениями.
  • Определяющее слово согласованно по числу и роду с существительным, которое оно модифицирует.
  • Прилагательное согласовано по числу и полу с существительным, которое оно модифицирует.
  • Глагол согласован с подлежащим.

В идеале этот анализ сгенерирует следующую версию перевода:

image

Машинный перевод на базе фраз


Машинный перевод на базе фраз — это самая простая и популярная версия статистического машинного перевода. Сегодня он по-прежнему является основной «рабочей лошадкой» и используется в крупных онлайн-сервисах по переводу.

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

image

Эта модель перевода основана на трех базовых методах:

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

Следовательно, на базе исходного предложения будет построена следующая таблица (это упрощенная форма, в реальности было бы еще множество вариантов, связанных с каждым словом):

image

Далее из этой таблицы генерируются тысячи возможных вариантов перевода предложения, например:

image

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

В этом подходе целевая языковая модель крайне важна и мы можем получить представление о качестве результата, просто поискав в Интернете:

image

Поисковые алгоритмы интуитивно предпочитают использовать последовательности слов, которые являются наиболее вероятными переводами исходных с учетом таблицы изменения порядка. Это позволяет с высокой точностью генерировать правильную последовательность слов на целевом языке.

В этом подходе нет явного или неявного лингвистического или семантического анализа. Нам было предложено множество вариантов. Некоторые из них лучше, другие — хуже, но, на сколько нам известно, основные онлайн-сервисы перевода используют именно эту технологию.

Нейронный машинный перевод


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

image

Нейронный машинный перевод имеет следующие особенности:

  • «Анализ» называется кодированием, а его результатом является загадочная последовательность векторов.
  • «Перенос» называется декодированием и непосредственно генерирует целевую форму без какой-либо фазы генерации. Это не строгое ограничение и, возможно, имеются вариации, но базовая технология работает именно так.

Сам процесс разбит на две фазы. В первой каждое слово исходного предложения проходит через «кодер», который генерирует то, что мы называем «исходным контекстом», опираясь при этом на текущее слово и предыдущий контекст:

image

Последовательность исходных контекстов (ContextS 1,… ContextS 5) являет внутренней интерпретацией исходного предложения по треугольнику Вокуа и, как упоминалось выше, представляет из себя последовательность чисел с плавающей запятой (обычно 1000 чисел с плавающей запятой, связанных с каждым исходным словом). Пока мы не будем обсуждать, как кодировщик выполняет это преобразование, но хотелось бы отметить, что особенно любопытным является первоначальное преобразование слов в векторе «float».

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

Предположим, что вам нужно вообразить разные объекты с вариациями по форме и цвету в двумерном пространстве. При этом объекты, находящиеся ближе всего друг к другу должны быть похожи. Ниже приведен пример:

image

На оси абсцисс представлены фигуры и там мы стараемся поместить наиболее близкие по этому параметру объекты другой формы (нам нужно будет указать, что делает фигуры похожими, но в случае этого примера это кажется интуитивным). По оси ординат располагается цвет — зеленый между желтым и синим (расположено так, потому что зеленый является результатом смешения желтого и синего цветов, прим. пер.) Если бы у наших фигур были разные размеры, мы бы могли добавить этот третий параметр следующим образом:

image

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

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

Следовательно, слова, обладающие общими свойствами и признаками будут расположены близко друг к другу. Например, можно представить, что слова определенной части речи — это одно измерение, слова по признаку пола (если таковой имеется) — другое, может быть признак положительности или отрицательности значения и так далее.

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

Вернемся к процессу перевода. Второй шаг имеет следующий вид:

image

На этом этапе формируется полная последовательность с упором на «исходный контекст», после чего один за другим целевые слова генерируются с использованием:

  • «Целевого контекста», сформированного в связке с предыдущим словом и предоставляющего некоторую информацию о состоянии процесса перевода.
  • Значимости «контекстного источника», который представляет собой смесь различных «исходных контекстов» опираясь на конкретную модель под названием «Модель внимания» (Attention Model). Что это такое мы разберем в другой статье. Если кратко, то «Модели внимания» выбирают исходное слово для использование в переводе на любом этапе процесса.
  • Ранее приведенного слова с использованием вложения слов для преобразования его в вектор, который будет обрабатываться декодером.

Перевод завершается, когда декодер доходит до этапа генерации фактически последнего слова в предложении.

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

Примеры перевода для сравнения


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

image
image

Мы видим, что машинный перевод на базе фраз, интерпретирует «render» как смысл — за исключением очень идиоматического варианта «оказание помощи». Это можно легко объяснить. Выбор значения зависит либо от проверки синтаксического значения структуре предложения, либо от семантической категории объекта.

Для нейронного машинного перевода видно, что слова «help» и «assistance» обрабатываются правильно, что показывает некоторое превосходство, а также очевидную способность этого метода получать синтаксические данные на большом расстоянии между словами, что мы более детально рассмотрим в другой публикации.

image
image

На этом примере опять видно, что нейронный машинный перевод имеет семантические различия с двумя другими способами (в основном они касаются одушевленности, обозначает слово человека или нет).

Однако отметим, что было неправильно переведено слово «rounds», которое в данном контексте имеет значение слова «bullet». Мы объясним этот типа интерпретации в другой статье, посвященной тренировке нейронных сетей. Что касается перевода на базе правил, то он распознал только третий смысл слова «rounds», который применяется в отношении ракет, а не пуль.

image
image

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

Другие варианты со словом «crime» показали тот же результат…

Переводчики работающие на базе слов и фраз так же не ошиблись, так как использовали те же глаголы, приемлемые в обоих контекстах.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334342/


Cравнение российских операторов предоставляющих облачные услуги

Пятница, 28 Июля 2017 г. 13:47 + в цитатник

Я долго ждал и просил автора исследования 2014 года повторить его. Не дождался, несмотря на регулярные просьбы. Видимо, представляя какой титанический труд предстоит, автор эту идею откладывал.  Но так совпало, что не только мне, но и моей знакомой для ее компании потребовались облачные услуги, и она предложила мне свою помощь по сбору информации. Так родилась шальная идея повторить статью. Возражений у автора предыдущего обзора не было, поэтому мы принялись за дело, взяв за основу его методику подсчета
В этот раз в обзор вошли 36 компаний, а совместная работа по сбору и анализу информации затянулась аж на 5 месяцев. Конфигурацию мы взяли, опираясь на предыдущее сравнение  с поправкой на требования компании моей знакомой.


Итак, запрос мы отправили в следующие компании:


ActiveCloud, AWS (Amazon), Azure (дистрибьютером выступил Comparex)*, b2b.beeline.ru, Clodo, Cloud One, Cloud4Y, CloudLITE **, 1cloud, Croc, DataFort, DataLine, De Novo, DepoCloud, e-Style Telecom, Flops, infoboxcloud.ru, IT Lite, IT-Grad, LanCloud, Linx, M1 Cloud, АЙТеко и MakeCloud***, Oncloud, Orange, Parking, Rackspace, Rentacloud, Selectel, Softline, Корус Консалтинг, Мегафон, Облакотека, Ростелеком О7, РТКОМ.


* Изначально диалог вели с представителями Azure, а для более подробного расчет при предоставлении услуг нас перевели на дистрибьютера Comparex


** CloudLITE интернет-магазин облачных ресурсов от  Dataline.


***Айтеко и Makecloud предоставляют услуги одной компании — Сервионика. Параметры облаков у них отличаются. Далее в таблицах отдельно будет Makecloud и Сервионика.


Запрашиваемая конфигурация:


1)Сайт на CentOS. 1CPU, 2Gb RAM, 50Gb;
2)  AD, DNS. 1CPU, 2Gb RAM, 50Gb;
3) CRM (ОС Windows). 2CPU, 4Gb RAM, 80Gb;
4) MS Exchange SaaS (с антивирусом и антиспамом). 45 ящиков 1GB;
5) Антивирус на все нужные сервера;
6) Резервное копирование каждый день на все серверы, глубина 14 дней;
7) Файловый сервер. 1CPU, 4Gb RAM, 200Gb;
8)  Сервер приложений 3CPU, 5RAM, 40Gb;
9) SQL  сервер 4CPU, 8RAM, 140 Gb;
10) Проброс USB ключа 1шт.
11) Терминальный сервер – 2 шт. 6CPU, 13 Gb RAM, 60Gb на каждый. На 45 пользователей;
12) Балансировщик для терминальников. 1CPU, 2Gb RAM, 30Gb;
13)  IP ATC (как SaaS) на 45 пользователей;
14) 5 VPN каналов;
15) 15 мегабит гарантированный канал интернет.


Итого необходимо:


CPU (гарантия 100%): 18
RAM (гарантия 100%): 54 Gb
SSD: 710 Gb
MS Windows Server  + 45 UserCAL
MS Remote Desktop 45 user
Ящики MS exchange – 45шт  по 2 Gb каждый
Антивирус по модели SaaS – 7 шт
Резервное копирование по модели SaaS  на все сервера  и сервисы. Глубина хранения информации – минимум неделя (14 дней). Частота создания – каждый день.
1C на 20 пользователей/Бухгалтерия Проф
1С сервер лицензия
MS Exchange SaaS (с антивирусом и антиспамом)
Канал 15 мбит
VPN канал – 5 шт
Проброс USB ключа 1шт.
MS SQL лицензия для 1С
IP АТС требования (45 сотрудников, сервер телефонии c записью разговоров).


Мы сократили количество вопросов представителям компании и было задано 17 вопросов:


  1. Используемые гипервизоры?
  2. Какие используются процессоры и сервера? Наименование производителя и серия.
  3. Какая система хранения используется? Производитель, модель?
  4. Какой уровень TIER дата-центра?
  5. Какой дата-центр? Где располагается?
  6. Возможность размещения на 2х площадках? Возможность размещения за рубежом?
  7. Возможность почасового биллинга? (Цена от этого меняется?)
  8. Возможность постоплаты?
  9. Какой SLA без доплаты Вы обеспечиваете?
  10. Какова гарантия ресурсов CPU, RAM, HDD, Network?
  11. Что входит в базовую поддержку?
  12. Поддержка 24x7 бесплатна?
  13. Применяется ли штатно технологии типа VMware High Availability (автоматический перезапуск в случае выхода сервера из строя, ~5-10 минут на запуск виртуальной машины)
  14. Сколько телеком операторов используется для отказоустойчивости AS?
  15. Есть тестовый доступ? На сколько дней?
  16. Как скоро возможно предоставить тестовый доступ?
  17. Возможен ли тестовый доступ под запрашиваемые выше ресурсы?

Выбыли


  • Мегафон был готов из запрашиваемых услуг предложить только облачную телефонию.
  • DepoCloud сообщили, что закрывают свой облачный бизнес и не готовы предоставить услуги.
  • Orange несмотря на все наши просьбы не сделал предварительного расчета, так как они сначала должны провести техническое обследование объекта, при этом описание необходимых сервисов вполне достаточно для расчета.
  • Clodo по-прежнему могут предложить инфраструктуру только на Linux
  • А Cloud One так и не предоставили расчета, несмотря на наши самые упорные просьбы, звонки и письма, аргументируя тем, что наши вопросы выглядят «подозрительно».

Как оценивали


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


+ + (супер-отлично – функционал или решение превосходящее запросы/ожидания)


+ (отлично – функционал или решение присутствует и полностью удовлетворяет запросам)


+ (средне – функционал или решение частично присутствует, существуют ограничения)


- (плохо – функционал или решение полностью отсутствует и не удовлетворяет запросам)


— - (супер-плохо – функционал или решение крайне не удовлетворяет запросам/ожиданиям)


? (информация отсутствует, то есть, вопрос был задан, но ответ не был предоставлен.


Тех, кто выбыл, но ответил на первый запрос, я в сравнительных таблицах пометил желтым маркером.


Коммуникация и скорость реакции


Нами было отправлено 795 писем и получено 668! Всего звонков было 284. Сами представляете, какой это гигантский объем информации. В процессе сбора, я просил свою знакомую, указывать время реакции компаний на ее запросы. Все запросы мы старались направить через сайт. Если с сайта не поступало ответа, то писали письма, если и письма не помогали, что случалось нередко, звонили лично и оставляли запрос.
Под предоставлением коммерческого предложения, подразумеваем расчет по заданным нами ресурсам. Иногда  менеджеры компаний высылали пару строчек в письме, где не хватало половины услуг или просто описание тарифов–это мы не засчитывали как первое предоставление КП и просили выслать полное. 


Компания


Время ответа (реакции)


Время выставления КП с момента обращения


ActiveCloud


несколько часов +


через 4 дня + -


Azure


несколько  часов +


через 1 день +


Amazon


4 часа +


через 3 дня + -


b2b.beeline.ru


через день +


через 3 недели - -


Clodo


через два дня + -


не предоставляют windows хостинг


Cloud4Y


несколько часов +


на следующий день +


CloudOne


несколько часов +


не предоставили КП - -


Croc


несколько часов +


через 4 дня + -


DataFort


2 дня + -


через 6 дней - -


DataLine


несколько часов +


через 7 дней - -


De Novo


несколько часов +


через 2 недели - -


DepoCloud


не ответили на запрос - -


закрывают свой облачный бизнес


e-Style Telecom


несколько минут +


через 2 дня +


infoboxcloud.ru


несколько минут +


через 2 дня +


IT Lite


1 день +


через 6 дней - -


IT-Grad


минута +


через 1 день +


Linx


через 1 день +


через 7 дней - -


M1 Cloud


2 часа +


на следующий день +


MakeCloud


несколько часов +


через 2 недели - -


o7.com


несколько дней +


через 3 дня + -


Oncloud


на следующий день +


через 25 дней - -


Orange


несколько часов +


КП только после физического обследования - -


Parking


через 2 дня + -


через 2 дня +


Rackspace


несколько минут +


через 22 дня - -


Rentacloud


несколько минут +


через 6 дней - -


Selectel


несколько минут +


через 5 дней - -


Softline


через 5 часов +


через день +


Корус Консалтинг


через 5 часов +


через 2 недели - -


Мегафон


через день +


предоставляют только АТС -


Облакотека


на следующий день +


через 5 дней - -


РТКОМ (rtcloud)


через 30 минут +


через месяц - -


Flops


несколько часов +


несколько часов +


1cloud


несколько часов +


через 5 дней - -


cloudlite


несколько часов +


сначала написали что отдали в Dataline, после повторного запроса, после повторного запроса через 2 дня + -


LanCloud


в течение минут +


через день +


Сервионика


несколько часов +


через 2 недели - -



Большинство компаний реагировали на запрос в течение нескольких часов, а вот DataFort, Clodo и Parking потребовалось два дня, чтобы ответить. С КП все оказалось сложнее, только 15 компаний уложились в срок от 1 до 4 дней, остальным потребовалось от недели до месяца, чтобы сформировать предложение.


Ответы на вопросы:


Теперь перейдем к ответам на технические вопросы и посмотрим, что за последние годы изменилось у компаний.


Компания


Используемые гипервизоры


Процессоры, сервер


Какой TIER у ЦОД?


Какой ДЦ и где?


ActiveCloud


KVM +


 Huawei, и HP – разное оборудование. Процессоры — INTEL Xeon +


Tier 3 +


Даталайн в Москве +


Azure


нет информации ?


нет информации ?


нет информации ?


нет информации ?


Amazon


HVM и PV +


t2 и m4, Intel Xeon +


TIER III +


Ирландия и Германия  + +


b2b.beeline.ru


VMware ESXi +


Cisco UCS B200M3 2xE5-2680 v2, 768GB +


TIA/EIA-942 +


Два ЦОД, г. Москва, связанные собственными каналами связи, точки присутствия на М9/М10 + +


Cloud4Y


vCloud Director, VMware vSphere 6U2 +


Blade HP C7000, BL460c G8-G9. Intel Xeon E5-2670, E5-2680v4 +


TIER-3 +


2 ЦОД Москва, Санкт-Петербург,
Нидерланды, Франкфурт + +


Croc


RedHat KVM, Microsoft Hyper-V, VMware ESXi +


Dell PowerEdge R720, процессоры Intel Xeon E5-2670 и E5-2690 с частотой 2,6-3 GHz +


TIER3 +


2 ЦОД Москва + +


DataFort


VMware ESXi, Microsoft Hyper-V +


Cisco UCS B200M3 2xE5-2680 v2, 768GB RAM +


TIER3 +


1) ул. 8 марта, д. 14, Tier 3 2)ул. Остаповский, д.22 стр. 16  + +


DataLine


VMware и Hyper-V  +


Intel® Xeon® CPU E7-8867 v3 @ 2.50GHz +


TIER3 +


Москва +


De Novo


VMWare +


Cisco UCS +


ЦОД уровня TIER III по классификации Uptime Institute +


 ДЦ в Киеве +


e-Style Telecom


Hyper-V +


cpu -E5, сервера HP и Supermicro +


Tier 3 +


Дата-центр e-Style Telecom, Москва, ул. Пришвина, д. 8, корпус 1 +


infoboxcloud.ru


Hyper-V Failover Clustering +


Huawei E9000 +


Tier III Design +


Москва, ул. Шарикоподшипниковская, 13 +


IT Lite


Hyper-V +


SuperMicro с процессорами E5-2630v3 +


Tier-3 (Stordata), Tier-3+ (Iхcellerate) +


ДЦ Stordata и ДЦ Ixcelellerate + +


IT-Grad


VMware vSphere 6.0. +


NetApp, Dell, HP, Cisco и Juniper +


Tier 3 +


Москва, Санкт-Петербург + +


Linx


VMware ESXI 5.5 +


EMC Flex POD (с использованием оборудования Cisco UCS B200) +


Tier 3 +


ЦОД Санкт-Петербург +


M1 Cloud


     VMware vCloud Director +


HP +


Tier 3 +


ЦОД М1 Москва +


MakeCloud


KVM OpenStack +


Intel Xeon Processor E5-2620, E5-2660
Серверы:
Depo Storm 3350
IBM X3550M4 +


Tier III +


Дата-центр «ТрастИнфо», Москва +


o7.com*


Hyper-V/Vmware +


Intel Xeon 2,7 ГГц, серверное оборудование IBM +


ЦОД соответствует требованиям Tier-III +


• Москва М10 (Сущевский вал, д.26)
• Новосибирск (ул. Менделеева, д.1)
• Москва М9 (ул. Бутлерова, д.7)
• Адлер (ул. Ленина, д.3)
+ +


Oncloud


VMWare vSphere +


HP DL 580G7/G8, Intel E7-4870/ E7-4890v2 +


Tier 3 +


Safedata г. Москва и                                                       Ixcellerate г. Москва + +


Parking


Hyper-V +


Hewlett-Packard Enterprise +


Tier3 +


В Москве, во Владимире + +


Rackspace


OpenStack +


Dells and HP +


Не используют сертификацию TIER3, но имеют SLA 99.999%  +


2 ДЦ в Лондоне + +


Rentacloud


VMware/HyperV +


Процессоры Intel E5, Сервера Dell, Intel +


Tier 3 +


StoreData (Москва) +


Selectel


Openstack KVM +


Intel Xeon E5-2670v3 или e5-2680v4. Серверы Supermicro +


Tier 3, но в процессе сертификации +


Санкт-Петербург +


Softline


VMWare +


Процессоры Intel, Сервера Cisco +


TIER 3 +


ЦОДы на ул. Боровая д 7,  на Алтуфьевское ш. д.33Г + +


Корус Консалтинг


VMware vSphere 6.0. +


NetApp, Dell, HP, Cisco и Juniper +


Tier 3 +


Москва, Санкт-Петербург + +


Облакотека


 Hyper-V 2012 +


Supermicro и Dell +


Tier3 +


ЦОДы компании Даталайн на Коровинском ш. и Боровой ул + +


РТКОМ (rtcloud)


VMWare +


HP BL 460C Gen 9 типовой узел: HP, 2 процессора (CPU), 12 ядер на процессор, Intel Xeon E5 2680 v3 – 2.50GHz +


Соответствие уровню надежности Tier III (сертификат отсутствует) +


Москва, Новосибирск, Ростов-на-Дону, Красноярск + +


Flops


QEMU/KVM +


процессоры Xeon e5 2620 и промышленные x86 сервера +


Tier 3+ +


ДЦ IXcellerate Moscow One +


1cloud


Vmware +


CISCO UCS B200 с процессорами E5 (20 cores, 3.0GHz, 384Gb RAM) +


Tier III +


ЦОД SDN Санкт-Петербург, Выборгское шоссе, 503 к. 12 +


cloudlite


Vmware +


Huawei FusionServer RH5885 V3 на базе процессоров Intel Xeon E7 +


Tier III +


Москва, NORD 3 по адресу: улица Боровая д. 7 стр. 10 +


LanCloud


Hyper-V 2012 R2 + AzurePck +


HP DL380/Huawei RH2288, Xeon E5-26xx V2/V3/V4 – 2,4-2,8 ГГц +


ЦОД сертификацию Uptime Institute не проходил -


ЦОД «Агава-Север», г. Долгопрудный, ул. Жуковского, д.3. 4км. от Москвы +


Сервионика


ESXi vCloud Director +


HP ProLiant BL460c Gen8
Процессоры: Intel® Xeon® Processor E5-2660 (2.20 GHz, 20M Cache, 8 Cores, 95W, 8.00 GT/s Intel® QPI) +


Tier III +


Дата-центр «ТрастИнфо», Москва +



* Ростелеком О7 предлагают два решения на разных гипервизорах. Далее если ответы по платформам отличаются, то они даны в двух строках.


Самой распространенной платформой остается VMWare, однако ряд компаний предлагают и другие платформы, что в некоторых случаях может удешевить решения. Практически все компании имеют ЦОДы уровня TIER 3. А вот Rackspace данную сертификацию не использует, зато уверяет, что уровень доступности даже выше, чем у TIER 3.


Компания


Какая СХД?


Применяется ли штатно технологии
типа VMware High Availability (автоматический перезапуск в
 случае выхода сервера из строя,
 ~5-10 минут на запуск виртуальной машины)?


ActiveCloud


Cisco,  Huawei +


нет


Azure


нет информации ?


нет информации ?


Amazon


gp2 +


VMware Cloud +


b2b.beeline.ru


EMC VNX5600, HP 3Par 7400 +


да +


Cloud4Y


СХД SSD AllFlash, дублированные контроллеры. До 1 млн IOPS. +


да +


Croc


IBM mid-range уровня (4 штуки, 2 на каждый ЦОД) и all-flash массивы Violin Memory +


Вендорские технологии по HA/DR-решениям не входят в стоимость, но все ресурсы на уровне железа зарезервированы средствами гипервизора KVM.+


DataFort


EMC VNX5600, HP 3par 7400 +


да +


DataLine


не предоставили информацию


да +


De Novo


нет информации ?


нет информации ?


e-Style Telecom


Своя СХД построенная на ПО Linux + -


да +


infoboxcloud.ru


Huawei OceanStor 5300 +


Да, все ВМ в кластере Hyper-V Failover Cluster +


IT Lite


 Infortrend ESDS 3024B +


отказоустойчивость обеспечивается резервным копированием Acronis


IT-Grad


 NetApp V6240, V8040 с использованием flash кэширования и SSD дисков. +


да +


Linx


EMC SCALEIO (с использованием нескольких СХД NettApp DS4246) +


да +


M1 Cloud


HP 3PAR StoreServ 7400 и NetApp FAS3250 +


да +


MakeCloud


NetAPP FAS8020 +


миграция выполняется силами администратора


o7.com


СХД на базе решения Dell, Hitachi, Huawei +


нет


o7.com


СХД на базе решения Dell, Hitachi, Huawei +


да, при использовании виртуализации Vmware +


Oncloud


HDS HUS VM/IBM Storwize v7000 +


да +


Parking


нет информации ?


да, Hyper-V +


Rackspace


нет информации ?


нет информации ?


Rentacloud


в основном Netapp +


да +


Selectel


СХД на базе платформ Supermicro, логически Openstack Ceph +


При падении физического хоста виртуальные серверы автоматически мигрируют на другие хосты +


Softline


NetApp  FAS8040, FAS2552 +


да +


Корус Консалтинг


 NetApp V6240, V8040 с использованием flash кэширования и SSD дисков. +


Да, High Availability +


Облакотека


СХД Dell +


да +


РТКОМ (rtcloud)


EMC VNX, HP 3PAR +


да +


Flops


СХД Ceph +


При аварии на физической ноде сервер перезапускается на другом гипервизоре в течение нескольких минут +


1cloud


 NetApp V6240 и FAS8040 +


да +


cloudlite


СХД VMware VSAN +


да +


LanCloud


HP MSA 2040 SAN, Huawei OceanStore 2600T и, самая мощная: Huawei OceanStore 5500 V3, которая выдаёт до 320 000 IOPS +


Hyper-V,   все машины по умолчанию в кластере High Availability +


Сервионика


HP 3PAR StoreServ 10400 IBM StorWize V7000 IBM XIV +


да +



Среди используемых СХД в лидерах решения NetApp, HP 3par и Huawei. Подавляющее большинство компаний указало, что штатно применяет автоматический перезапуск в  случае выхода сервера из строя. Здесь особых изменений за прошедшее время не произошло.


Компания


Постоплата?


Гарантия ресурсов CPU,
RAM, HDD, Network?


Возможность почасового биллинга?
Цена от этого меняется?


SLA


ActiveCloud


предоплата -


гарантированы +


да, не меняется +


99,5% + -


Azure


нет информации ?


нет информации ?


нет информации ?


нет информации ?


Amazon


и постоплата и предоплата +


нет информации ?


да/не сообщили +


 


b2b.beeline.ru


постоплата +


99,93% + -


Лицензии и хранилища — месячная оплата, ресурсы — почасовая. + -


99,93% +


Cloud4Y


постоплата +


100% +


да, не меняется +


99,95% +


Croc


постоплата +


100% +


да, меняется + -


SLA 99,9 или 8 ч. 45 мин. +


DataFort


постоплата +


100% +


да, но ресурсы не гарантированы + -


99.93% +


DataLine


постоплата +


уровень доступности 99,982% + -


да, дороже + -


99,982% + +


De Novo


постоплата +


нет информации ?


    Биллинг посуточный -


99,95% +


e-Style Telecom


предоплата -


100% +


нет -


99,99% + +


infoboxcloud.ru


предоплата -


RAM гарантированы + -


помесячная -


99,982% + +


IT Lite


только предоплата -


все ресурсы гарантированы +


нет -


99,98% + +


IT-Grad


постоплата и предоплата +


гарантия ресурсов +


да, увеличится + -


99,9% +


Linx


постоплата +


уровень доступности 99,98% + -


биллинг раз в сутки -


99,98% + +


M1 Cloud


постоплата +


100% +


да, меняется + -


99,9% +


MakeCloud


предоплата -


100% +


нет -


99,5% + -


o7.com


постоплата +


гарантированы +


Начисления происходят по суткам -


99,9% +


Oncloud


постоплата +


 


да, не меняется +


99,5% + -


Parking


предоплата -


уровень доступности 99,85% + -


нет -


99,85% + -


Rackspace


предоплата, постоплата возможна только через месяц работы + -


нет информации


да +


99.99% + +


Rentacloud


Возможны оба варианта +


гарантированы +


Нет, только ежемесячный -


99,9% +


Selectel


предоплата -


если зарезервированы, то да + -


почасовой, цена та же +


99,98% + +


Softline


предоплата, для постоплаты документы для кредитного отдела + -


99,9%, отображено по SLA + -


возможен ежедневный по договоренности + -


99,9% +


Корус Консалтинг


постоплата и предоплата +


Ресурсы гарантированны, модель Reservation Pool +


да, увеличится + -


99,9% +


Облакотека


постоплата +


100% +


да, не меняется +


99,9% +


РТКОМ (rtcloud)


предоплата, при наличии положительного опыта работы возможна постоплата + -


100% +


да +


99,9% +


Flops


работаем на условиях предоплаты, при наличии коммерческой истории мы можем рассмотреть вариант постоплаты + -


уровень доступности 99,9% + -


только поминутный +


99,9% +


1cloud


Предоплата -


гарантированы +


списания каждые 10 мин. +


99,9% +


cloudlite


оплата ежедневно


количество доступных ресурсов отображается в личном кабинете


только для услуги «Виртуальный сервер VDS|VPS + -


99,95% +


LanCloud


Предоплата -


RAM, SSD 100%  + -


нет -


99,9% +


Сервионика


предоплата и постоплата +


100% +


почасовая возможна +


99,982% + +



Около 50% операторов готовы работать с клиентом на условиях постоплаты, что конечно, очень удобно. С гарантией ресурсов не все однозначно. Ряд компаний ссылался на свой уровень доступности, что не совсем то, что нас интересовало. От уточняющих вопросов уходили, ссылаясь на свой SLA. Оставим это на их совести. Честнее поступили компании LanCloud и infoboxcloud, пояснив, что именно гарантировано. SLA если сравнить в среднем с прошлым обзором, у операторов стал выше. Особенно отличились Rackspace, о которых упоминалось ранее, и e-Style Telecom.


Компания


Поддержка 24x7 бесплатна? Что входит?


Компания работает с НДС? На все услуги в КП распостраняется НДС?


Сколько телеком операторов используется для отказоустойчивости


ActiveCloud


24/7 бесплатна. Включена круглосуточная техническая поддержка. Максимальный срок реакции 4 часа +


да +


до 20 + +


Azure


нет информации ?


нет -


нет информации ?


Amazon


Тех. Поддержка платная -


нет


нет информации ?


b2b.beeline.ru


да, 24/7.Билайн обеспечивает 1 линию поддержки. SD и тех. службы работают круглосуточно (24х7х365). Так же большинство работ в пулах Заказчиков согласовываются и проводятся в ночное время.


да +


Для отказоустойчивости организовано несколько стыков для подключения услуг Интернет и выделенных каналов связи Билайн. +


Cloud4Y


Да, 24/7 бесплатна. Время реакции до 15 минут +


да +


4 +


Croc


Да, до уровня гипервизора +


да +


4 +


DataFort


да, 24/7 +


да +



Метки:  

[Перевод] Будни сисадминские: 17 типичных ситуаций

Пятница, 28 Июля 2017 г. 13:41 + в цитатник
Если вы работаете в ИТ-сфере, то наверняка сталкиваетесь с проблемами, которые другие люди даже не понимают. Стоит ли говорить о переработках, инцидентах пользователей, людях, которые даже не пытаются понять, чем же вы занимаетесь на работе… не каждый готов разделить ваши головные боли.

Наша команда подготовила вольный пятничный перевод прекрасных комиксов о банальных жизненных ситуациях системных администраторов. А у вас тоже всё так?



Мы в Alloy Software делаем софт для системных администраторов, тестируем его, непрерывно общается с админами и знаем, сколько всего ежечасно сваливается на их инженерные головы. И готовы подписаться под каждой ситуацией — наблюдаем их непрерывно.

1. Пойти на работу, чтобы решить кучу проблем с компьютерами. Вернуться домой, чтобы решить ещё больше таких проблем.



2. Развивается фобия текстовых сообщений. Одно из двух: либо алерт от сервера, либо уведомление о новом тикете.



3. Вроде вы не уборщица, а всегда разгребаете оставленный пользователем ИТ-беспорядок (например, пролитый чай, сок, кефир).



4. Пытаетесь объяснить, почему Интернет и Wi-Fi не одно и то же.

5. Вы научились так быстро ходить по офисным коридорам, чтобы пользователи не успевали вас остановить.

6. Использованные в очередной раз не к месту и неправильно фразы типа «Единая информационная панель», «Облако», «Бигдата», приводят в вас в ярость.



7. Одно слово: вредоносы.



8. Два слова: распутывать провода.



9. Три слова: не могу напечатать.



10. Четыре слова: помоги мне сбросить пароль!



11. Так много ошибок пользователей!

12. Устали просить пользователей выключить и снова включить (но это реально работает!).

13. Мечетесь в агонии, слушая разговоры гуманитариев о технологиях (о которых они просто без понятия).

14. Распугиваете не настолько гикнутых друзей своим техно-жаргоном.



15. Несмотря на непрерывные напоминания, все жестко игнорируют создание тикетов.

16. Зато на вас обрушивается поток телефонных звонков, электронной почты и тикетов, если что-то нужно починить ПРЯМО СЕЙЧАС СРОЧНО ВАЖНО.

17. Отдых и расслабление? Что это вообще? Даже в отпуске на необитаемом острове вы всегда на связи.



БОНУС. Очень мало людей знают о Дне системного администратора SysAdmin Day, который отмечается сегодня, в последнюю пятницу июля.



С Днём системного администратора! Толковых пользователей, успешных обновлений, адекватных боссов. А мы, Alloy Software, продолжаем работать — только для вас!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334340/



Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1070 1069 [1068] 1067 1066 ..
.. 1 Календарь