Guava - open-source библиотека, разработанная в основном инженерами компании Google, в которой есть множество полезных утилит для написания эффективного и красивого кода. В Guava решено множество типичных задач, которые часто возникают при работе с примитивами, строками, коллекциями, параллельными вычислениями, кэшированием данных и многим другим. В докладе поговорим о возможностях, которые предоставляет Guava, рассмотрим примеры использования утилит библиотеки.
Guava - open-source библиотека, разработанная в основном инженерами компании Google, в которой есть множество полезных утилит для написания эффективного и красивого кода. В Guava решено множество типичных задач, которые часто возникают при работе с примитивами, строками, коллекциями, параллельными вычислениями, кэшированием данных и многим другим. В докладе поговорим о возможностях, которые предоставляет Guava, рассмотрим примеры использования утилит библиотеки.
Лекция #5. Введение в язык программирования Python 3Яковенко Кирилл
Web-программирование
Лекция #5. Введение в язык программирования Python 3
Цикл лекций читается в Омском государственном университете им. Ф.М.Достоевского на факультете компьютерных наук.
Лектор: Яковенко Кирилл Сергеевич.
Доклад о дизайне кода в функциональном стиле на C++, представленный вниманию плюсовиков на C++ User Group Novosibirsk 2014.
В качестве демонстрационного проекта была реализована игра "Амбер" по мотивам "Хроник Амбера" Р. Желязны.
https://github.com/graninas/Amber
Лекция 2. Всё, что вы хотели знать о функциях в Python.Roman Brovko
Синтаксис объявления функций. Упаковка и распаковка аргументов. Ключевые аргументы и аргументы по умолчанию. Распаковка и оператор присваивания. Области видимости, правило LEGB, операторы global и nonlocal. Функциональное программирование, анонимные функции. Функции map, filter и zip. Генераторы списков, множеств и словарей. Немного о PEP 8.
Лекция 4. Строки, байты, файлы и ввод/вывод.Roman Brovko
Строковые литералы и сырые строки. Строки и Юникод. Основные методы работы со строками. Модуль string. Байты. Кодировки. Файлы и файловые объекты. Методы работы с файлами. Модуль io
Лекция #5. Введение в язык программирования Python 3Яковенко Кирилл
Web-программирование
Лекция #5. Введение в язык программирования Python 3
Цикл лекций читается в Омском государственном университете им. Ф.М.Достоевского на факультете компьютерных наук.
Лектор: Яковенко Кирилл Сергеевич.
Доклад о дизайне кода в функциональном стиле на C++, представленный вниманию плюсовиков на C++ User Group Novosibirsk 2014.
В качестве демонстрационного проекта была реализована игра "Амбер" по мотивам "Хроник Амбера" Р. Желязны.
https://github.com/graninas/Amber
Лекция 2. Всё, что вы хотели знать о функциях в Python.Roman Brovko
Синтаксис объявления функций. Упаковка и распаковка аргументов. Ключевые аргументы и аргументы по умолчанию. Распаковка и оператор присваивания. Области видимости, правило LEGB, операторы global и nonlocal. Функциональное программирование, анонимные функции. Функции map, filter и zip. Генераторы списков, множеств и словарей. Немного о PEP 8.
Лекция 4. Строки, байты, файлы и ввод/вывод.Roman Brovko
Строковые литералы и сырые строки. Строки и Юникод. Основные методы работы со строками. Модуль string. Байты. Кодировки. Файлы и файловые объекты. Методы работы с файлами. Модуль io
What’s good for the leader is good for the team. A strong leader with weak team, just as a strong team with a weak leader are destined for failure. If the goals and direction are not clear, if the team is not focused and putting sufficient effort towards the goal, it won’t be attained. I was only as good as the teams I managed, and I’d like to think I helped some of them grow. I’ve been very fortunate to have some Superstars and strong players on my teams, but I’ve also had some that did not succeed.
Here’s a list that is not only from a leader’s perspective, but also considers the traits I observed in my Superstars.
What’s good for the leader is good for the team. A strong leader with weak team, just as a strong team with a weak leader are destined for failure. If the goals and direction are not clear, if the team is not focused and putting sufficient effort towards the goal, it won’t be attained. I was only as good as the teams I managed, and I’d like to think I helped some of them grow. I’ve been very fortunate to have some Superstars and strong players on my teams, but I’ve also had some that did not succeed.
Here’s a list that is not only from a leader’s perspective, but also considers the traits I observed in my Superstars. (You know who you are, too!)
What’s good for the leader is good for the team. A strong leader with weak team, just as a strong team with a weak leader are destined for failure. If the goals and direction are not clear, if the team is not focused and putting sufficient effort towards the goal, it won’t be attained. I was only as good as the teams I managed, and I’d like to think I helped some of them grow. I’ve been very fortunate to have some Superstars and strong players on my teams, but I’ve also had some that did not succeed.
Here’s a list that is not only from a leader’s perspective, but also considers the traits I observed in my Superstars. (You know who you are, too!)
Solit 2014, EcmaScript 6 in Action, Трухин Юрий solit
Юрий Трухин, Россия. Эксперт по облачным технологиям хостинговой компании InfoboxCloud. В прошлом – обладатель статуса Microsoft Most Valuable Professional. Гик, стратег, разработчик. Подробнее на trukhin.com
«Обзор InfoboxCloud для разработчиков». Development секция. Высокий уровень подготовки. Для разработчиков.
В этом докладе будет рассказано об устройстве InfoboxCloud из первых рук, о деталях внутренней реализации, о том, какую пользу несет облако для разработчиков и о будущем InfoboxCloud. Будут рассмотрены 2 кита облачных технологий: IaaS и PaaS без vendor-lock. Отличная возможность спросить обо всём, что касается PaaS/IaaS непосредственно архитектора и разработчика этих систем.
«EcmaScript 6 in Action». Development секция. Для разработчиков.
Поговорим о том, как жизнь разработчиков изменится с приходом нового стандарта.
В лекции подробно рассмотрены тонкие моменты языка JavaScript, с которыми часто возникают основные проблемы. Наглядные примеры и рецепты помогают лучше понять его особенности.
Клиент-сайд изобилует кучей различных транспортов, и зачастую непонятно, какой взять для решения той или иной задачи. В данной лекции рассказывается об особенности каждого транспорта и области применимости.
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)Ontico
TypeScript – светлое будущее ES6 уже вчера.
Почему не "Кофе"? Чай полезней.
Что не так с Flow от Facebook?
Реальная практика использования: плюсы и минусы.
Не VisualStudio единым. Особенности работы в других IDE.
Интеграция с уже существующим JS кодом.
Использование совместно с RequireJS. Подводные камни.
Использование TypeScript совместно с React.
TypeScript и Angular.
Плюшки, которых нет в ES6/7 (пока нет): [static] enum, интерфейсы, private, protected, декораторы... Что дают и зачем?
Olexandra Dmytrenko
QA Automating at EPAM Systems
I'll show you how to switch from writing standard code using good old Java7 into writing it using functional way presented in Java8. The training is counted on beginners in the subject who like discovering the new horizons or for those who want to become more firm in using the new lambda features.
Developers want to make very few errors in their code and to spot them as early as possible: with the help of unit tests, or earlier, during compilation, or best of all, immediately after they typed something wrong in their IDE. This is what static code analyzers are for. Some of them are built-in, others need to be run separately, some check just about any code, the others require it to be annotated first, and there are tools that are a little bit of all. Do the ends justify the means? Is it even worth trying? What kind of errors can be spotted by static code analysis? How sure can we be if what an analyzer gives us is a real error or a false positive? This talk hopefully helps you answer these questions.
2. С чем имеем дело?
● ОО подход основан на прототипах;
● Отсутствие пространств имен;
● Отсутствие ограничения области видимости;
● Отсутствие строгой типизации;
● Отсутствие проверки статических элементов.
3. Прототипное программирование
function Human() {
console.log('Human constructor called');
}
Human.prototype = {
sayHuman: function() { alert('I am a Human!'); },
sayHello: function() { alert('Hello world!'); }
}
// human.__proto__ = instance of Object
var human = new Human();
function Man() {
console.log('Man constructor called');
}
Man.prototype = new Human();
Man.prototype.sayMan = function() {
alert('I am a Man!');
}
function Woman() {
console.log('Woman constructor called');
}
Woman.prototype = new Human();
Woman.prototype.sayWoman = function() {
alert('I am a Woman!');
}
var peter = new Man(); // peter.__proto__ = instance of Human
var olga = new Woman(); // olga.__proto__ = instance of Human
4. Интерфейсы. Классика
interface MyInterface1 {
public function add($param1);
public function remove($param1);
}
interface MyInterface2 {
public function display($param1, $param2);
}
class MyClass implements MyInterface1, MyInterface2 {
public function add($param1) { ... }
public function remove(param1) { ... }
public function display($param1, $param2) { ... }
}
5. Эмуляция интерфейсов в JS с помощью комментариев
/*
interface MyInterface1 {
function add(param1);
function remove(param1);
}
interface MyInterface2 {
function display(param1, param2);
}
*/
var MyClass = function() { // implements MyInterface1, MyInterface2
...
};
MyClass.prototype.add = function(param1) { ... };
MyClass.prototype.remove = function(param1) { ... };
MyClass.prototype.display = function(param1, param2) { ... };
6. Эмуляция интерфейсов в JS с помощью простой проверки
/*
interface MyInterface1 {
function add(param1);
function remove(param1);
}
interface MyInterface2 {
function display(param1, param2);
}
*/
var MyClass = function() {
this.implementsInterfaces = ['MyInterface1', 'MyInterface2'];
...
};
function someClient(someInstance) {
if(!implements(someInstance, 'MyInterface1', 'MyInterface2')) {
throw new Error("Object does not implement a required interface.");
}
...
}
// Проверяет, есть ли в массиве object.implementsInterfaces нужные названия интерфейсов
function implements(object) {
...
}
7. Эмуляция интерфейсов в JS. Объекты + проверка методов
var MyInterface1 = new Interface('MyInterface1', ['add', 'remove']);
var MyInterface2 = new Interface('MyInterface2', ['display']);
var MyClass = function() { // implements MyInterface1, MyInterface2
...
};
function someClient(someInstance) {
// выбросит Exception, если в object отсутствуют нужные методы
Interface.ensureImplements(someInstance, MyInterface1, MyInterface2));
...
}
8. Конструктор Interface
var Interface = function(name, methods) {
if(arguments.length != 2) {
throw new Error("Interface constructor called with " + arguments.length +
"arguments, but expected exactly 2.");
}
this.name = name;
this.methods = [];
for(var i = 0, len = methods.length; i < len; i++) {
if(typeof methods[i] !== 'string') {
throw new Error("Interface constructor expects method names to be passed in as a string.");
}
this.methods.push(methods[i]);
}
};
9. Статический метод Interface.ensureImplements
Interface.ensureImplements = function(object) {
if(arguments.length < 2) {
throw new Error("Function Interface.ensureImplements called with " +
arguments.length + "arguments, but expected at least 2.");
}
for(var i = 1, len = arguments.length; i < len; i++) {
var interface = arguments[i];
if(interface.constructor !== Interface) {
throw new Error("Function Interface.ensureImplements expects arguments"
+ "two and above to be instances of Interface.");
}
for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
var method = interface.methods[j];
if(!object[method] || typeof object[method] !== 'function') {
throw new Error("Function Interface.ensureImplements: object "
+ "does not implement the " + interface.name
+ " interface. Method " + method + " was not found.");
}
}
}
};
10. Инкапсуляция на соглашениях
var IHuman = new Interface('Human', ['getSurname', 'setSurname', 'getName', 'setName']);
var Human = function (surname, name) {
this.setSurname(surname);
this.setName(name);
}
Human.prototype = {
getSurname: function() {
return this._surname;
},
setSurname: function(surname) {
if (!this._isset(surname)) {
throw new Error('Surname is required')
};
this._surname = surname;
},
getName: function() {
return this._name;
},
setName: function(name) {
this._name = name || null;
},
_isset: function(s) {
if (s == undefined || typeof s != 'string') { return false; }
else { return true; }
}
}
11. Замыкания
Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся
каждый раз во время её выполнения. При этом вложенная внутренняя функция содержит ссылки
на локальные переменные внешней функции. Каждый раз при выполнении внешней функции
происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные
внешней функции.
function foo() {
var a = 10;
function bar() {
a *= 2;
return a;
}
return bar;
}
var baz = foo(); // baz is now a reference to function bar
baz(); // returns 20
baz(); // returns 40
baz(); // returns 80
var blat = foo(); // blat is another reference to bar
blat(); // returns 20
12. Инкапсуляция на замыканиях
var Human = function (newSurname, newName) {
var name, surname;
function isset(s) {
if (s == undefined || typeof s != 'string') { return false; } else { return true; }
};
// Privileged methods
this.getSurname = function() {
return surname;
};
this.setSurname = function(newSurname) {
if (!isset(newSurname)) { throw new Error('Surname is required') };
surname = newSurname;
};
this.getName = function() {
return name;
};
this.setName = function(newName) {
name = newName || null;
};
// Constructor code
this.setSurname(newSurname);
this.setName(newName);
}
Human.prototype = { // Public, non-privileged methods
talk: function() {
alert(this.getName() + this.getSurname());
}
};
13. Статические атрибуты и методы
var Human = (function () {
// Private static attribute and method
var count = 0;
function isset(s) { ... };
// Return the constructor
return function (newSurname, newName) {
// Private attributes
var name, surname;
// Privileged methods
this.getSurname = function() { ... };
this.setSurname = function(newSurname) { ... };
this.getName = function() { ... };
this.setName = function(newName) { ... };
// Constructor code
count++;
this.setSurname(newSurname);
this.setName(newName);
}
})();
// Public static method
Human.toUpperCase = function(s){ ... }
Human.prototype = { // Public, non-privileged methods
talk: function() { ... }
};
14. Константы - приватные статические атрибуты с getter-ом
var Human = (function () {
// Constant (created as private static attribute)
var CLASS_NAME = 'Human';
// Privileged static method
this.getCLASS_NAME() {
return CLASS_NAME;
}
// Return the constructor
return function (newSurname, newName) {
...
}
})();
15. Приватный объект с константами и getter-ом
var Human = (function () {
// Private static attributes.
var constants = {
CLASS_NAME: 'Human',
SOME_CONSTANT_1: 'Some value 1',
SOME_CONSTANT_2: 'Some value 2'
}
// Privileged static method.
this.getConstant(name) {
return constants[name];
}
// Return the constructor
return function (newSurname, newName) {
...
}
})();
16. Эмуляция классического наследования
/* Class Person */
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
/* Class Author */
function Author(name, books) {
Person.call(this, name); // Call the superclass's constructor in the scope of this
this.books = books; // Add an attribute to Author
}
Author.prototype = new Person(); // Set up the prototype chain
Author.prototype.constructor = Author; // Set the constructor attribute to Author
Author.prototype.getBooks = function() { // Add a method to Author
return this.books;
}
var author1 = new Author('Jeff Six', ['Application Security for the Android Platform']);
var author2 = new Author('Vandad Nahavandipoor', ['iOS 5 Programming Cookbook']);
17. Эмуляция классического наследования. Функция extend
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}
/* Class Person */
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
/* Class Author. */
function Author(name, books) {
Author.superclass.constructor.call(this, name);
this.books = books;
}
extend(Author, Person);
Author.prototype.getBooks = function() {
return this.books;
};
var author1 = new Author('Jeff Six', ['Application Security for the Android Platform']);
var author2 = new Author('Vandad Nahavandipoor', ['iOS 5 Programming Cookbook']);
18. Инкапсуляция при эмуляции классического наследования
● В подклассе имеется доступ только к публичным и привилегированным членам
родительского класса;
● Приватные члены родительского класса доступны в подклассах, а также извне
только через привилегированные методы самого родительского класса;
● Если есть необходимость в protected членах, принято соглашение использовать
подчеркивание, например var _myProtectedVar = null;
19. Прототипное наследование
/* Clone function */
function clone(object) {
function F() {}
F.prototype = object;
return new F;
}
/* Person Prototype Object */
var Person = {
name: 'default name',
getName: function() {
return this.name;
}
}
/* Author Prototype Object */
var Author = clone(Person);
Author.books = []; // Default value
Author.getBooks = function() {
return this.books;
}
var author1 = clone(Author); // Author-like object
author1.name = 'Jeff Six';
author1.books = ['Application Security for the Android Platform'];
var author2 = clone(Author); // Author-like object
author2.name = 'Vandad Nahavandipoor';
author2.books = ['iOS 5 Programming Cookbook'];
20. Mixin
/* Augment function. */
function augment(receivingClass, givingClass) {
for(var methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
/* Regular class */
var Class1 = function() {};
Class1.prototype = {
method1: function() {},
method2: function() {}
}
/* Mixin class */
var Class2 = function() {};
Class2.prototype = {
mixinMethod1: function() { alert('mixinMethod1 called'); },
mixinMethod2: function() { alert('mixinMethod2 called'); }
};
augment(Class1, Class2);
var myObj = new Class1();
myObj.mixinMethod1();
21. Singleton
/* Basic Singleton. */ /* Singleton with Private Members */
var Singleton = { MyNamespace.Singleton = (function() {
attribute1: true,
attribute2: 10, // Private members
method1: function() { var privateAttribute1 = false;
... var privateAttribute2 = [1, 2, 3];
}, function privateMethod1() {
method2: function(arg) { ...
... }
} function privateMethod2(args) {
}; ...
}
return {
// Public members
publicAttribute1: true,
publicAttribute2: 10,
publicMethod1: function() {
...
},
publicMethod2: function(args) {
...
}
};
})();
22. "Ленивое" инстанцирование
MyNamespace.Singleton = (function() {
var instance;
// All of the singleton code here
function constructor() {
var privateAttribute1 = false;
function privateMethod1() {
...
}
return {
publicAttribute1: true,
publicMethod1: function() {
...
}
}
}
return {
// Public members
getInstance: function() {
if(!instance) {
instance = constructor();
}
return instance;
}
}
})();
MyNamespace.Singleton.getInstance().publicMethod1(); // Call singleton method
23. Простая Фабрика
var CarFactory = {
createCar: function(model) {
var car;
switch(model) {
case 'bmw':
car = new BMW();
break;
case 'ford':
car = new Ford();
break;
case 'ferrari':
default:
car = new Ferrari();
}
Interface.ensureImplements(car, Car);
return car;
}
};
24. Фабричный метод - паттерн, порождающий классы
/* CarShop class (abstract). */
var CarShop = function() {};
CarShop.prototype = {
sellCar: function(model) {
var car = this.createCar(model);
car.prepare();
car.wash();
return car;
},
createCar: function(model) {
throw new Error('Unsupported operation on an abstract class');
}
};
● Используем абстрактный класс;
● Используем метод extend: extend(FordCarShop, CarShop);
● Используем при необходимости метод ensureImplements: Interface.ensureImplements
(car, Car).
25. Компоновщик. Пример использования - запоминание форм
var contactForm = new CompositeForm('contact-form', 'POST', 'contact.php');
var nameFieldset = new CompositeFieldset('name-fieldset');
nameFieldset.add(new InputField('first-name', 'First Name'));
nameFieldset.add(new InputField('last-name', 'Last Name'));
contactForm.add(nameFieldset);
var addressFieldset = new CompositeFieldset('address-fieldset');
addressFieldset.add(new InputField('address', 'Address'));
addressFieldset.add(new InputField('city', 'City'));
addressFieldset.add(new SelectField('state', 'State', stateArray));
contactForm.add(addressFieldset);
contactForm.add(new TextareaField('comments', 'Comments'));
body.appendChild(contactForm.getElement());
addEvent(window, 'unload', contactForm.save);
addEvent(window, 'load', contactForm.restore);
addEvent('save-button', 'click', nameFieldset.save);
addEvent('restore-button', 'click', nameFieldset.restore);
26. Декораторы функций
Выглядит это так:
function upperCaseDecorator(func) {
return function() {
return func.apply(this, arguments).toUpperCase();
}
}
Можно применять с пользой:
var gCollection = new YMaps.GeoObjectCollection();
gCollection = new TimeProfiler(gCollection); // Декорируем все методы профайлером
gCollection.add([
new YMaps.Placemark(new YMaps.GeoPoint(37.518234, 55.708937)),
new YMaps.Placemark(new YMaps.GeoPoint(37.514146, 55.722294)),
new YMaps.Placemark(new YMaps.GeoPoint(37.514146, 55.722225)),
new YMaps.Placemark(new YMaps.GeoPoint(37.514146, 55.722236))
]);
gCollection.removeAll();
С помощью декоратора TimeProfiler, в консоли будет напечатано время выполнения
методов add и removeAll.
27. Тренируем внимание
● Расширение встроенных прототипов языка - зло;
● Не забываем писать var;
● Учитываем зависимость производительности от длины цепочек прототипов;
● Цикл for in проходит по всей цепочке прототипов. Решение - hasOwnProperty;
● JavaScript не резервирует свойство с именем hasOwnProperty, но можно делать
так: ({}).hasOwnProperty.call(obj, 'propertyName');
● Обходить обычный массив с помощью for in - зло;
● Ключевое слово this ссылается на контекст вызова, но его можно явно задать при
call и apply;
● arguments не является наследником Array, у него нет push, pop, slice и т.д.;
● Помним про высасывание определений вверх ближайшей области видимости;
● Используем instanceof только собственных типов. Для стандартных типов - зло;
● eval - зло: а) безопасность; б) косвенный вызов и выход из локального scope;
● for(var i = 0; i < 10; i++) {
setTimeout(function() { console.log(i); }, 1000);
}
Числа 0-9 не будут напечатаны, так как анонимная функция сохраняет ссылку на
переменную i, которая в момент вызова будет равна 10. Решение:
for(var i = 0; i < 10; i++) {
(function(e) { setTimeout(function() { console.log(e); }, 1000); })(i);
}
29. Внимание, оператор typeof
Результат работы typeof (простите, но так исторически сложилось...):
Значение [[Class]] = Object.prototype.toString. Тип
call(myObj)
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function в Nitro/V8)
new RegExp("meow") RegExp object (function в Nitro/V8)
{} Object object
new Object() Object object