SlideShare uma empresa Scribd logo
1 de 130
Baixar para ler offline
Парсим CSS
performance tips & tricks
Роман Дворнов
Avito
Москва, сентябрь 2016
Руководитель 

фронтенда в Avito
Основной интерес – SPA
Open source:

basis.js, CSSO, 

component-inspector, 

csstree и другие
За любую движуху, 

кроме голодовки ;)
Парсим CSS
(зачем? почему? как дальше жить?)
3
tinyurl.com/csstree-intro
Начало истории (доклад)
CSSTree
CSSTree – самый быстрый 

и детальный парсер CSS
5
Как я до этого докатился?
Чуть меньше года назад 

я стал мейнтейнером CSSO
(минификатор CSS)
7
github.com/css/csso
CSSO работал на основе
парсера Gonzales
8
github.com/css/gonzales
Проблемы
• Не развивается с 2013
• Неудобный формат AST, местами странный
• Много ошибок
• Запутанная и сложная кодовая база
• Медленный, потребляет много памяти, GC
9
Парсер – последнее, что я
собирался трогать…
10
Альтернатива?
Парсеров CSS на JavaScript
достаточно много
12
Частые проблемы
• Заброшены и не развиваются
• Устарели (не поддерживают новое в CSS)
• Содержат ошибки
• Неудачная структура
• Медленные
13
Наилучшим выбором может
быть парсер из PostCSS
14
postcss.org
Плюсы PostCSS
• Развивается и поддерживается
• Хорошо справляется с синтаксисом CSS и даже
будущим + tolerant mode
• Сохраняет информацию о форматировании
• Удобное API для работы с AST
• Быстрый
15
Основная проблема:
селекторы и значения свойств
остаются не разобранными
(хранятся в виде строки)
16
Это вынуждает разработчиков
• Использовать костыли
• Писать свои парсеры
• Использовать дополнительные парсеры:

postcss-selector-parser

postcss-value-parser
17
Переход на PostCSS означал написание
собственных парсеров селекторов и
свойств, что не сильно отличается от
написания парсера целиком
18
Регулярный рефакторинг приводит к тому,
что парсер может быть полностью переписан 

(это норма 😳)
19
Парсер выделен в отдельный проект
github.com/csstree/csstree
20
Скорость
CSSO – история ускорения
(в том числе про парсер)
22
tinyurl.com/csso-speedup
В предыдущих сериях (доклад)
После выступления разогнал
парсер еще :)
23
* Вдохновленный общением с Вячеславом @mraleph Егоровым
24
CSSTree: 24 ms
Mensch: 31 ms
CSSOM: 36 ms
PostCSS: 38 ms
Rework: 81 ms
PostCSS Full: 100 ms
Gonzales: 175 ms
Stylecow: 176 ms
Gonzales PE: 214 ms
ParserLib: 414 ms
bootstrap.css v3.3.7 (146Kb)
github.com/postcss/benchmark
Не детальное AST
Детальное AST
PostCSS Full =
+ postcss-selector-parser
+ postcss-value-parser
Epic fail
как выяснилось позже, я вынес
не ту версию парсера
25
😱
github.com/csstree/csstree/commit/57568c758195153e337f6154874c3bc42dd04450
26
CSSTree: 24 ms
Mensch: 31 ms
CSSOM: 36 ms
PostCSS: 38 ms
Rework: 81 ms
PostCSS Full: 100 ms
Gonzales: 175 ms
Stylecow: 176 ms
Gonzales PE: 214 ms
ParserLib: 414 ms
bootstrap.css v3.3.7 (146Kb)
github.com/postcss/benchmark
На FrontTalks был
показан результат
до разгона
13 ms
Парсеры: курс молодого бойца
Основные шаги
• Токенизация
• Построение дерева (лексер)
28
Токенизация
30
• whitespaces – [ nrtf]+
• keyword – [a-zA-aZ…]+
• number – [0-9]+
• string – "string" или 'string'
• comment – /* comment */
• punctuation – [;,.#{}[]()…]
Разбиение текста на токены
31
.foo {
width: 10px;
}
[
'.', 'foo', ' ', '{',
'n ', 'width', ':',
' ', '10', 'px', ';',
'n', '}'
]
Нужна дополнительная информация
о токене: тип и локация
32
На этапе токенизации мы
знаем тип и позицию,
считать их после – дорого
33
.foo {
width: 10px;
}
[
{
type: 'FullStop',
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
Сборка
35
function getSelector() {
var selector = {
type: 'Selector',
sequence: []
};
// main loop
return selector;
}
Сборка
36
for (;currentToken < tokenCount; currentToken++) {
switch (tokens[currentToken]) {
case TokenType.Hash: // #
selector.sequence.push(getId());
break;
case TokenType.FullStop: // .
selector.sequence.push(getClass());
break;
…
}
Main loop
37
{
"type": "StyleSheet",
"rules": [{
"type": "Atrule",
"name": "import",
"expression": {
"type": "AtruleExpression",
"sequence": [ ... ]
},
"block": null
}]
}
Результат
История ускорения #2
39
[
{
type: 'FullStop',
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
Стоимость токена:
24 + 5 * 4 + массив =
min 50 bytes per token
В нашем проекте ~1Mb CSS
254 062 токена
=
min 12.7 Mb
Прелюдия: меняем подход
Посчитать все токены, а потом 

из них собирать AST – проще,
но ведет к лишним затратам памяти
и медленней
41
Scanner
(ленивый токенайзер)
42
43
scanner.token // текущий токен или null
scanner.next() // переход к следующему токену
scanner.lookup(N) // заглядывание вперед, возвращает
// токен на N-ой позиции от текущей
Основное API
44
• lookup(N)

заполняет буфер токенов до позиции N, если еще
не заполнен, возвращает N-1 токен из буфера
• next()

делает shift из lookup буфера, если он не пустой,
либо читает новый токен
Создается столько же токенов, 

но нужно меньше памяти в один
момент времени
45
Проблема:
заставляем CG плакать работать
46
Уменьшаем стоимость токенов:
«многоходовочка»
48
[
{
type: 'FullStop',
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
Строковые обозначения
удобны при отладке, но
они не выходят за рамки
сканера и можно
заменить на числа
49
[
{
type: FULLSTOP,
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
…
// '.'.charCodeAt(0)
var FULLSTOP = 46;
…
50
[
{
type: 46,
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
51
[
{
type: 46,
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
Можно не хранить
подстроку – это особенно
расточительно для
одиночных символов;
к тому же многие многие
конструкции собираются
из нескольких токенов –
эффективнее брать одну
подстроку вместо
конкатенации нескольких
52
[
{
type: 46,
value: '.',
offset: 0,
line: 1,
column: 1
},
…
]
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
53
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Look, Ma!
No strings just numbers!
54
Да не просто Array, а TypedArray
Массив 

объектов
Массивы 

чисел
Array vs. TypedArray
• Не могут содержать дырок
• В теории быстрее (т.к. меньше проверок)
• Хранятся вне heap (если достаточно большие)
• Предзаполнены нулями
55
56
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1
4
4
4
4
17 per token
(кол-во токенов) 254 062 x 17 = 4.3Mb
4.3Mb vs. 12.7Mb(min)
57
Хьюстон, у нас проблемы:
TypedArray фиксированной длины,

а мы не знаем сколько токенов будет
58
59
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1
4
4
4
4
17 per token
(кол-во символов) 983 085 x 17 = 16.7Mb
16.7Mb vs. 12.7Mb (min)
60
16.7Mb vs. 12.7Mb (min)
60
Не повод сдаваться, 

давайте немного
подумаем…
61
start = [ 0, 5, 6, 7, 9, 11, …, 35 ]
end = [ 5, 6, 7, 9, 11, 12, …, 36 ]
61
start = [ 0, 5, 6, 7, 9, 11, …, 35 ]
end = [ 5, 6, 7, 9, 11, 12, …, 36 ]
…
62
start = [ 0, 5, 6, 7, 9, 11, …, 35 ]
end = [ 5, 6, 7, 9, 11, 12, …, 36 ]
offset = [ 0, 5, 6, 7, 9, 11, …, 35, 36 ]
start = offset[i]
end = offset[i + 1]
+
=
63
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1
4
4
4
4
13 per token
983 085 x 13 = 12.7Mb
64
a {
top: 0;
}
lines = [
1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3
]
columns = [
1, 2, 3, 4,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1
]
lines & columns
64
a {
top: 0;
}
lines = [
1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3
]
columns = [
1, 2, 3, 4,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1
]
lines & columns
65
line = lines[offset];
column = offset - lines.lastIndexOf(line - 1, offset);
lines & columns
65
line = lines[offset];
column = offset - lines.lastIndexOf(line - 1, offset);
lines & columns
Ок для коротких строк,
нужно кешировать для
длинных
66
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1
4
4
4
4
9 per token
983 085 x 9 = 8.8Mb
67
8.8Mb vs. 12.7Mb(min)
Меньше операций со строками
«Убийцы» производительности*
• RegExp
• Конкатенация строк
• toLowerCase/toUpperCase
• substr/substring
• …
69
* Засоряют GC и он все портит
«Убийцы» производительности*
• RegExp
• Конкатенация строк
• toLowerCase/toUpperCase
• substr/substring
• …
70
Без этого никак, 

но от остального
можно избавиться
* Засоряют GC и он все портит
71
var start = scanner.tokenStart;
…
scanner.next();
…
scanner.next();
…
return source.substr(start, scanner.tokenEnd);
Нет конкатенации!
72
function cmpStr(source, start, end, str) {
if (end - start !== str.length) {
return false;
}
for (var i = start; i < end; i++) {
var sourceCode = source.charCodeAt(i);
var strCode = str.charCodeAt(i - start);
if (sourceCode !== strCode) {
return false;
}
}
return true;
}
Сравнение строк
73
function cmpStr(source, start, end, str) {
if (end - start !== str.length) {
return false;
}
for (var i = start; i < end; i++) {
var sourceCode = source.charCodeAt(i);
var strCode = str.charCodeAt(i - start);
if (sourceCode !== strCode) {
return false;
}
}
return true;
}
Сравнение строк
Быстрое отсечение
по длине
74
function cmpStr(source, start, end, str) {
if (end - start !== str.length) {
return false;
}
for (var i = start; i < end; i++) {
var sourceCode = source.charCodeAt(i);
var strCode = str.charCodeAt(i - start);
if (sourceCode !== strCode) {
return false;
}
}
return true;
}
Сравнение строк
Сравниваем 

код за кодом
Как сравнивать 

без учета регистра*?
75
* То есть без toLowerCase/toUpperCase
Эвристика
• Сравниваем с заранее известными строками (str)
• Заранее заданные строки всегда в нижнем
регистре и содержат только латинские буквы
• Читал я как то в твиттере…
76
Чтобы перевести из верхнего регистра в
нижний, нужно выставить 6-й бит в 1
(работает только для латинских букв)
'A' = 01000001
'a' = 01100001
'A'.charCodeAt(0) | 32 === 'a'.charCodeAt(0)
77
78
function cmpStr(source, start, end, str) {
…
for (var i = start; i < end; i++) {
…
// source[i].toLowerCase()
if (sourceCode >= 65 && sourceCode <= 90) { // 'A' .. 'Z'
sourceCode = sourceCode | 32;
}
if (sourceCode !== strCode) {
return false;
}
}
…
}
Сравнение строк без учета регистра
Бенефиты
• Часто срабатывает быстрое отсечение
• Нет получения подстрок (не давим на CG)
• Нет получения временных строк 

(результат toLowerCase/toUpperCase)
• Операция сравнения не производит мусор
79
Отказываемся от массивов
(от слова совсем)
Что не так с массивами
• Если растить массив, то происходит
копирование памяти + нагрузка на GC
• Мы не можем заранее знать размер массива
81
Решение?
82
Двусвязные списки
83
84
Плюсы
• Не вызывает копирование памяти
• Не засоряет CG при построении AST
• Мы получаем next/prev
85
Всё это и многое другое позволило
уменьшить потребление памяти,
нагрузку на GC 

и ускорить вдвое
86
Но это еще не конец 😋
87
История ускорения #3
неделя после FrontTalks
Общие моменты
• Упрощение структуры AST
• Меньше потребление памяти, переиспользование
• list.map().join() -> цикл + конкатенация
• и по мелочи…
89
И снова про стоимость токенов
91
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1 types
4 offsets
4
4 lines
4
9 per token
983 085 x 9 = 8.8Mb
lines можно считать не всегда и лениво
92
93
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1 types
4 offsets
4
4 lines
4
5 per token
983 085 x 5 = 4.9Mb
Действительно ли для offsets
нужно 32 бита?
Эвристика: вряд ли кто-то будет парсить
CSS больше 16Mb
94
95
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 1, 47, 47, 4, 4, 47, 5, …, 3 ]
96
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 1, 47, 47, 4, 4, 47, 5, …, 3 ]
offsetAndType[i] = type[i] << 24 | offset[i]
+
=
97
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 1, 47, 47, 4, 4, 47, 5, …, 3 ]
offsetAndType[i] = type[i] << 24 | offset[i]
offsetAndType = [ 16777216, 788529157, … ]
+
=
98
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 1, 47, 47, 4, 4, 47, 5, …, 3 ]
offsetAndType[i] = type[i] << 24 | offset[i]
offsetAndType = [ 16777216, 788529157, … ]
offset = offsetAndType[i] & 0xFFFFFF;
type = offsetAndType[i] >> 24;
+
=
99
[
{
type: 46,
start: 0,
end: 1,
line: 1,
column: 1
},
…
]
Uint8Array
Uint32Array
Uint32Array
Uint32Array
Uint32Array
1 types
4 offsets
4
4 lines
4
4 per token
983 085 x 4 = 3.9Mb
3.9-7.8 Mb vs. 12.7 Mb (min)
100
101
class Scanner {
...
next() {
var next = this.currentToken + 1;
this.currentToken = next;
this.tokenStart = this.tokenEnd;
this.tokenEnd = this.offsetAndType[next + 1] & 0xFFFFFF;
this.tokenType = this.offsetAndType[next] >> 24;
}
}
Два чтения из массива – 

как то не круто…
102
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 1, 47, 47, 4, 4, 47, 5, …, 3 ]
103
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 0, 1, 47, 47, 4, 4, 47, 5, …, 3 ]
103
offset = [ 0, 5, 6, 7, 9, 11, 11, …, 1234 ]
type = [ 0, 1, 47, 47, 4, 4, 47, 5, …, 3 ]
…
104
class Scanner {
...
next() {
var next = this.currentToken + 1;
this.currentToken = next;
this.tokenStart = this.tokenEnd;
this.tokenEnd = this.offsetAndType[next + 1] & 0xFFFFFF;
this.tokenType = this.offsetAndType[next + 1] >> 24;
}
}
Теперь можно в одно
чтение
105
class Scanner {
...
next() {
var next = this.currentToken + 1;
this.currentToken = next;
this.tokenStart = this.tokenEnd;
next = this.offsetAndType[next + 1];
this.tokenEnd = next & 0xFFFFFF;
this.tokenType = next >> 24;
}
}
-50% чтений (~250k)
Переиспользование
Сканер каждый раз создавал
новые массивы на каждый
разбор
107
Сканер каждый раз создавал
новые массивы на каждый
разбор
107
Новая стратегия
• По дефолту создается буфер в 16Kb
• Создается новый буфер, только если он мал
для разбираемого CSS
• Значительный прирост скорости, особенно в
сценариях разбора малых фрагментов CSS
108
109
CSSTree: 24 ms
Mensch: 31 ms
CSSOM: 36 ms
PostCSS: 38 ms
Rework: 81 ms
PostCSS Full: 100 ms
Gonzales: 175 ms
Stylecow: 176 ms
Gonzales PE: 214 ms
ParserLib: 414 ms
bootstrap.css v3.3.7 (146Kb)
github.com/postcss/benchmark
13 ms 7 ms
Текущий результат
И это еще не конец… 😋
110
Минутка «рекламы»
CSSTree – 

не только про скорость
112
Новая фича*:
Разбор и матчинг синтаксиса
CSS значений
113
* Пока уникальная среди CSS парсеров
Пример
114
115
csstree.github.io/docs/syntax.html
Документация синтаксиса
116
csstree.github.io/docs/validator.html
Валидатор синтаксиса CSS значений
117
var csstree = require('css-tree');
var syntax = csstree.syntax.defaultSyntax;
var ast = csstree.parse('… your css …');
csstree.walkDeclarations(ast, function(node) {
if (!syntax.match(node.property.name, node.value)) {
console.log(syntax.lastMatchError);
}
});
Свой валидатор в 8 строк
Кое что еще
• csstree-validator – npm пакет + консольная команда
• stylelint-csstree-validator – плагин для stylelint
• gulp-csstree – плагин для gulp
• SublimeLinter-contrib-csstree – плагин для Sublime Text
• vscode-csstree – плагин для VS Code
• csstree-validator – плагин для Atom



More is coming…
118
Заключение
Хотите чтобы ваш JavaScript
работал так же быстро как Си,
сделайте его похожим на Си
120
Изучайте алгоритмы, структуры данных,
как работают JS-движки и GC – 

у вас будет больше вариантов для
оптимизаций
121
– К.О.
Доклады по теме
• CSSO – история ускорения

tinyurl.com/csso-speedup
• Парсим CSS

tinyurl.com/csstree-intro
122
github.com/csstree/csstree
123
Нужен ваш фидбек
Роман Дворнов
@rdvornov
github.com/lahmatiy
rdvornov@gmail.com
Вопросы?
github.com/csstree/csstree

Mais conteúdo relacionado

Mais procurados

Developing highload servers with Java
Developing highload servers with JavaDeveloping highload servers with Java
Developing highload servers with JavaAndrei Pangin
 
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...Unigine Corp.
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуcorehard_by
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Alexander Granin
 
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...Ontico
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSSRoman Dvornov
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типовcorehard_by
 
Clojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaClojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaOlim Saidov
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Pavel Tsukanov
 
Haskell
HaskellHaskell
HaskellDevDay
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Pythonru_Parallels
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
 
Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAlex Tumanoff
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в TarantoolTimur Safin
 

Mais procurados (20)

Developing highload servers with Java
Developing highload servers with JavaDeveloping highload servers with Java
Developing highload servers with Java
 
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почему
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
 
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSS
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Clojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaClojure – есть ли жизнь после Java
Clojure – есть ли жизнь после Java
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Clojure #1
Clojure #1Clojure #1
Clojure #1
 
Haskell
HaskellHaskell
Haskell
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey Teplyakov
 
Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 

Destaque

Что надо знать о HTTP/2
Что надо знать о HTTP/2Что надо знать о HTTP/2
Что надо знать о HTTP/2Badoo Development
 
Классическое программирование для фронтендеров
Классическое программирование для фронтендеровКлассическое программирование для фронтендеров
Классическое программирование для фронтендеровBadoo Development
 
Как мы общаемся с пользователями на 46 языках и понимаем друг друга
Как мы общаемся с пользователями на 46 языках и понимаем друг другаКак мы общаемся с пользователями на 46 языках и понимаем друг друга
Как мы общаемся с пользователями на 46 языках и понимаем друг другаBadoo Development
 
Багфиксинг процесса разработки в iOS: взгляд с двух сторон
Багфиксинг процесса разработки в iOS: взгляд с двух сторонБагфиксинг процесса разработки в iOS: взгляд с двух сторон
Багфиксинг процесса разработки в iOS: взгляд с двух сторонBadoo Development
 
Мобильный веб: назад в будущее
Мобильный веб: назад в будущееМобильный веб: назад в будущее
Мобильный веб: назад в будущееBadoo Development
 
Технологии vs коммуникации: что важнее?
Технологии vs коммуникации: что важнее?Технологии vs коммуникации: что важнее?
Технологии vs коммуникации: что важнее?Badoo Development
 
Как автотесты ускоряют релизы в OK.ru
Как автотесты ускоряют релизы в OK.ruКак автотесты ускоряют релизы в OK.ru
Как автотесты ускоряют релизы в OK.ruBadoo Development
 
TechLeads meetup: Макс Лапшин, Erlyvideo
TechLeads meetup: Макс Лапшин, ErlyvideoTechLeads meetup: Макс Лапшин, Erlyvideo
TechLeads meetup: Макс Лапшин, ErlyvideoBadoo Development
 
TechLeads meetup: Андрей Шелёхин, Tinkoff.ru
TechLeads meetup: Андрей Шелёхин, Tinkoff.ruTechLeads meetup: Андрей Шелёхин, Tinkoff.ru
TechLeads meetup: Андрей Шелёхин, Tinkoff.ruBadoo Development
 
Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programsBadoo Development
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
"Новые возможности MySQL 5.7"
"Новые возможности MySQL 5.7""Новые возможности MySQL 5.7"
"Новые возможности MySQL 5.7"Badoo Development
 
"Геолокация в Badoo", Андрей Воликов (Badoo)
"Геолокация в Badoo", Андрей Воликов (Badoo)"Геолокация в Badoo", Андрей Воликов (Badoo)
"Геолокация в Badoo", Андрей Воликов (Badoo)Badoo Development
 
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)AvitoTech
 
"PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио...
"PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио..."PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио...
"PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио...Badoo Development
 
"Производительность MySQL: что нового?"
"Производительность MySQL: что нового?""Производительность MySQL: что нового?"
"Производительность MySQL: что нового?"Badoo Development
 
"Великолепный API без Rest", Констатин Якушев (Badoo)
 "Великолепный API без Rest", Констатин Якушев (Badoo) "Великолепный API без Rest", Констатин Якушев (Badoo)
"Великолепный API без Rest", Констатин Якушев (Badoo)Badoo Development
 
Golang в avito
Golang в avitoGolang в avito
Golang в avitoAvitoTech
 

Destaque (20)

Что надо знать о HTTP/2
Что надо знать о HTTP/2Что надо знать о HTTP/2
Что надо знать о HTTP/2
 
S.O.L.I.D-ый JavaScript
S.O.L.I.D-ый JavaScriptS.O.L.I.D-ый JavaScript
S.O.L.I.D-ый JavaScript
 
Классическое программирование для фронтендеров
Классическое программирование для фронтендеровКлассическое программирование для фронтендеров
Классическое программирование для фронтендеров
 
Как мы общаемся с пользователями на 46 языках и понимаем друг друга
Как мы общаемся с пользователями на 46 языках и понимаем друг другаКак мы общаемся с пользователями на 46 языках и понимаем друг друга
Как мы общаемся с пользователями на 46 языках и понимаем друг друга
 
Багфиксинг процесса разработки в iOS: взгляд с двух сторон
Багфиксинг процесса разработки в iOS: взгляд с двух сторонБагфиксинг процесса разработки в iOS: взгляд с двух сторон
Багфиксинг процесса разработки в iOS: взгляд с двух сторон
 
Мобильный веб: назад в будущее
Мобильный веб: назад в будущееМобильный веб: назад в будущее
Мобильный веб: назад в будущее
 
Технологии vs коммуникации: что важнее?
Технологии vs коммуникации: что важнее?Технологии vs коммуникации: что важнее?
Технологии vs коммуникации: что важнее?
 
Как автотесты ускоряют релизы в OK.ru
Как автотесты ускоряют релизы в OK.ruКак автотесты ускоряют релизы в OK.ru
Как автотесты ускоряют релизы в OK.ru
 
TechLeads meetup: Макс Лапшин, Erlyvideo
TechLeads meetup: Макс Лапшин, ErlyvideoTechLeads meetup: Макс Лапшин, Erlyvideo
TechLeads meetup: Макс Лапшин, Erlyvideo
 
TechLeads meetup: Андрей Шелёхин, Tinkoff.ru
TechLeads meetup: Андрей Шелёхин, Tinkoff.ruTechLeads meetup: Андрей Шелёхин, Tinkoff.ru
TechLeads meetup: Андрей Шелёхин, Tinkoff.ru
 
Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programs
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
"Новые возможности MySQL 5.7"
"Новые возможности MySQL 5.7""Новые возможности MySQL 5.7"
"Новые возможности MySQL 5.7"
 
"Геолокация в Badoo", Андрей Воликов (Badoo)
"Геолокация в Badoo", Андрей Воликов (Badoo)"Геолокация в Badoo", Андрей Воликов (Badoo)
"Геолокация в Badoo", Андрей Воликов (Badoo)
 
"Обзор Tarantool DB"
"Обзор Tarantool DB""Обзор Tarantool DB"
"Обзор Tarantool DB"
 
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
 
"PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио...
"PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио..."PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио...
"PostgreSQL для разработчиков приложений", Павел Лузанов, (Постгрес Профессио...
 
"Производительность MySQL: что нового?"
"Производительность MySQL: что нового?""Производительность MySQL: что нового?"
"Производительность MySQL: что нового?"
 
"Великолепный API без Rest", Констатин Якушев (Badoo)
 "Великолепный API без Rest", Констатин Якушев (Badoo) "Великолепный API без Rest", Констатин Якушев (Badoo)
"Великолепный API без Rest", Констатин Якушев (Badoo)
 
Golang в avito
Golang в avitoGolang в avito
Golang в avito
 

Semelhante a Парсим CSS

Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутAndrey Karpov
 
CSS глазами машин
CSS глазами машинCSS глазами машин
CSS глазами машинRoman Dvornov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Fwdays
 
Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...Andrey Karpov
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
CSSO — сжимаем CSS Роман Дворнов, Avito
 CSSO — сжимаем CSS Роман Дворнов, Avito CSSO — сжимаем CSS Роман Дворнов, Avito
CSSO — сжимаем CSS Роман Дворнов, Avitoit-people
 
Язык программирования PascalABC.NET 2015. Новые возможности
Язык программирования PascalABC.NET 2015. Новые возможностиЯзык программирования PascalABC.NET 2015. Новые возможности
Язык программирования PascalABC.NET 2015. Новые возможностиМихалкович Станислав
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибкиAndrey Karpov
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаPositive Hack Days
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаAndrey Karpov
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаAndrey Karpov
 
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Ontico
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 

Semelhante a Парсим CSS (20)

Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минут
 
CSS глазами машин
CSS глазами машинCSS глазами машин
CSS глазами машин
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
PascalABC.NET 2015-2016
PascalABC.NET 2015-2016PascalABC.NET 2015-2016
PascalABC.NET 2015-2016
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
 
Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
CSSO — сжимаем CSS Роман Дворнов, Avito
 CSSO — сжимаем CSS Роман Дворнов, Avito CSSO — сжимаем CSS Роман Дворнов, Avito
CSSO — сжимаем CSS Роман Дворнов, Avito
 
Язык программирования PascalABC.NET 2015. Новые возможности
Язык программирования PascalABC.NET 2015. Новые возможностиЯзык программирования PascalABC.NET 2015. Новые возможности
Язык программирования PascalABC.NET 2015. Новые возможности
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программиста
 
About Python
About PythonAbout Python
About Python
 
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 

Mais de Badoo Development

Viktar Karanevich – iOS Parallel Automation
Viktar Karanevich – iOS Parallel AutomationViktar Karanevich – iOS Parallel Automation
Viktar Karanevich – iOS Parallel AutomationBadoo Development
 
Как мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон ДовгальКак мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон ДовгальBadoo Development
 
Григорий Джанелидзе, OK.RU
Григорий Джанелидзе, OK.RUГригорий Джанелидзе, OK.RU
Григорий Джанелидзе, OK.RUBadoo Development
 
Андрей Сидоров, Яндекс.Браузер
Андрей Сидоров, Яндекс.БраузерАндрей Сидоров, Яндекс.Браузер
Андрей Сидоров, Яндекс.БраузерBadoo Development
 
Филипп Уваров, Avito
Филипп Уваров, AvitoФилипп Уваров, Avito
Филипп Уваров, AvitoBadoo Development
 
Cocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicCocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicBadoo Development
 
Cocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature developmentCocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature developmentBadoo Development
 
Alex Krasheninnikov – Hadoop High Availability
Alex Krasheninnikov – Hadoop High AvailabilityAlex Krasheninnikov – Hadoop High Availability
Alex Krasheninnikov – Hadoop High AvailabilityBadoo Development
 
Андрей Денисов – В ожидании мониторинга баз данных
Андрей Денисов – В ожидании мониторинга баз данныхАндрей Денисов – В ожидании мониторинга баз данных
Андрей Денисов – В ожидании мониторинга баз данныхBadoo Development
 
Александр Зобнин, Grafana Labs
Александр Зобнин, Grafana LabsАлександр Зобнин, Grafana Labs
Александр Зобнин, Grafana LabsBadoo Development
 
Илья Аблеев – Zabbix в Badoo: реагируем быстро и качественно
Илья Аблеев – Zabbix в Badoo: реагируем быстро и качественноИлья Аблеев – Zabbix в Badoo: реагируем быстро и качественно
Илья Аблеев – Zabbix в Badoo: реагируем быстро и качественноBadoo Development
 
TechLeads meetup: Алексей Рыбак, Badoo
TechLeads meetup: Алексей Рыбак, BadooTechLeads meetup: Алексей Рыбак, Badoo
TechLeads meetup: Алексей Рыбак, BadooBadoo Development
 
TechLeads meetup: Евгений Потапов, ITSumma
TechLeads meetup: Евгений Потапов, ITSumma TechLeads meetup: Евгений Потапов, ITSumma
TechLeads meetup: Евгений Потапов, ITSumma Badoo Development
 
Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»
Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»  Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»
Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов» Badoo Development
 
Как мы готовим MySQL
 Как мы готовим MySQL  Как мы готовим MySQL
Как мы готовим MySQL Badoo Development
 
Архитектура хранения и отдачи фотографий в Badoo
Архитектура хранения и отдачи фотографий в Badoo Архитектура хранения и отдачи фотографий в Badoo
Архитектура хранения и отдачи фотографий в Badoo Badoo Development
 
5 способов деплоя PHP-кода в условиях хайлоада
5 способов деплоя PHP-кода в условиях хайлоада5 способов деплоя PHP-кода в условиях хайлоада
5 способов деплоя PHP-кода в условиях хайлоадаBadoo Development
 
Git хуки на страже качества кода
Git хуки на страже качества кодаGit хуки на страже качества кода
Git хуки на страже качества кодаBadoo Development
 
Versioning strategy for a complex internal API
Versioning strategy for a complex internal APIVersioning strategy for a complex internal API
Versioning strategy for a complex internal APIBadoo Development
 

Mais de Badoo Development (20)

Viktar Karanevich – iOS Parallel Automation
Viktar Karanevich – iOS Parallel AutomationViktar Karanevich – iOS Parallel Automation
Viktar Karanevich – iOS Parallel Automation
 
Как мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон ДовгальКак мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон Довгаль
 
Григорий Джанелидзе, OK.RU
Григорий Джанелидзе, OK.RUГригорий Джанелидзе, OK.RU
Григорий Джанелидзе, OK.RU
 
Андрей Сидоров, Яндекс.Браузер
Андрей Сидоров, Яндекс.БраузерАндрей Сидоров, Яндекс.Браузер
Андрей Сидоров, Яндекс.Браузер
 
Филипп Уваров, Avito
Филипп Уваров, AvitoФилипп Уваров, Avito
Филипп Уваров, Avito
 
Cocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicCocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magic
 
Cocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature developmentCocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature development
 
Alex Krasheninnikov – Hadoop High Availability
Alex Krasheninnikov – Hadoop High AvailabilityAlex Krasheninnikov – Hadoop High Availability
Alex Krasheninnikov – Hadoop High Availability
 
Андрей Денисов – В ожидании мониторинга баз данных
Андрей Денисов – В ожидании мониторинга баз данныхАндрей Денисов – В ожидании мониторинга баз данных
Андрей Денисов – В ожидании мониторинга баз данных
 
Александр Зобнин, Grafana Labs
Александр Зобнин, Grafana LabsАлександр Зобнин, Grafana Labs
Александр Зобнин, Grafana Labs
 
Илья Аблеев – Zabbix в Badoo: реагируем быстро и качественно
Илья Аблеев – Zabbix в Badoo: реагируем быстро и качественноИлья Аблеев – Zabbix в Badoo: реагируем быстро и качественно
Илья Аблеев – Zabbix в Badoo: реагируем быстро и качественно
 
TechLeads meetup: Алексей Рыбак, Badoo
TechLeads meetup: Алексей Рыбак, BadooTechLeads meetup: Алексей Рыбак, Badoo
TechLeads meetup: Алексей Рыбак, Badoo
 
TechLeads meetup: Евгений Потапов, ITSumma
TechLeads meetup: Евгений Потапов, ITSumma TechLeads meetup: Евгений Потапов, ITSumma
TechLeads meetup: Евгений Потапов, ITSumma
 
Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»
Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»  Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»
Паша Мурзаков: Как 200 строк на Go помогли нам освободить 15 серверов»
 
Как мы готовим MySQL
 Как мы готовим MySQL  Как мы готовим MySQL
Как мы готовим MySQL
 
Архитектура хранения и отдачи фотографий в Badoo
Архитектура хранения и отдачи фотографий в Badoo Архитектура хранения и отдачи фотографий в Badoo
Архитектура хранения и отдачи фотографий в Badoo
 
5 способов деплоя PHP-кода в условиях хайлоада
5 способов деплоя PHP-кода в условиях хайлоада5 способов деплоя PHP-кода в условиях хайлоада
5 способов деплоя PHP-кода в условиях хайлоада
 
ChromeDriver Jailbreak
ChromeDriver JailbreakChromeDriver Jailbreak
ChromeDriver Jailbreak
 
Git хуки на страже качества кода
Git хуки на страже качества кодаGit хуки на страже качества кода
Git хуки на страже качества кода
 
Versioning strategy for a complex internal API
Versioning strategy for a complex internal APIVersioning strategy for a complex internal API
Versioning strategy for a complex internal API
 

Парсим CSS