PHP-Дайджест № 117 – свежие новости, материалы и инструменты (10 – 24 сентября 2017) |
Свежая подборка со ссылками на новости и материалы. В выпуске: PHP 7.2.0 RC 2, о будущем HHVM, предложения из PHP Internals, подборка чатов по PHP, видео с конференций и митапов, и многое другое.
Приятного чтения!
$$
и теперь предложен более простой вариант:$x = "hello"
|> 'strtoupper'
|> function($x) { return $x . " world"; };
// $x === "HELLO world"
Спасибо за внимание!
Если вы заметили ошибку или неточность — сообщите, пожалуйста, в личку.
Вопросы и предложения пишите на почту или в твиттер.
Прислать ссылку
Быстрый поиск по всем дайджестам
<- Предыдущий выпуск: PHP-Дайджест № 116
Метки: author pronskiy разработка веб-сайтов php блог компании zfort group дайджест php- ссылки symfony laravel zend wordpress hhvm |
Пишем для UEFI BIOS в Visual Studio. Часть 3 — русифицируем Front Page |
Метки: author DarkTiger системное программирование uefi bios |
Дайджест свежих материалов из мира фронтенда за последнюю неделю №281 (18 — 24 сентября 2017) |
|
Сложно ли сделать из мухи слона? |
к ИИ относятся задачи, которые компьютер решает заметно хуже человека.
В словаре перечислены все имена существительные «Орфографического словаря»
(106000 слов, 28-е издание, 1990 г.). [...] Набор текста осуществлён в 1996-98 годах игроками команды «Пузляры» (http://puzzle.ezakaz.ru) — Константином Кнопом, Яковом Зайдельманом, Валерием Тимониным, Виктором Кабановым, Дмитрием Филимоненковым.
Число загруженных слов (число вершин графа): 1501
Число ребер: 2402
Решение: (8 слов) муха-мула-кула-кила-килт-киот-клот-клон-слон
Затрачено времени: 4.59 сек.
муха-мура-бура-бора-кора-корн-коан-клан-улан-улар-удар-удав
мышка-мошка-кошка-корка-горка
шило-кило-коло-соло-сало-рало-рыло-мыло
баран-барон-басон-басок-бачок-бочок-борок-порок-порог-ворог-ворот
Число загруженных слов: 3391
Число ребер: 223
Максимальное расстояние: 9
Пары на максимальном расстоянии: закатывание-запихивание, запихивание-наматывание, обсаживание-отматывание, отматывание-отсиживание
Затрачено времени: 3821.45 сек.
Решение: (9 слов) запихивание-запахивание-запаривание-заваривание-заваливание-закаливание-накаливание-накалывание-накатывание-наматывание
Затрачено времени: 62.12 сек.
Метки: author third112 разработка игр программирование математика занимательные задачки алгоритмы ai искусственный интеллект компьютерные игры теория графов головоломки из мухи слона |
13-я статья об отрицательном опыте в работе с MS SQL Server |
select DB_NAME(t.database_id) as [DBName]
, SCHEMA_NAME(obj.schema_id) as [SchemaName]
, OBJECT_NAME(t.object_id) as [ObjectName]
, obj.Type as [ObjectType]
, obj.Type_Desc as [ObjectTypeDesc]
, ind.name as [IndexName]
, ind.Type as IndexType
, ind.Type_Desc as IndexTypeDesc
, ind.Is_Unique as IndexIsUnique
, ind.is_primary_key as IndexIsPK
, ind.is_unique_constraint as IndexIsUniqueConstraint
, t.[Database_ID]
, t.[Object_ID]
, t.[Index_ID]
, t.Last_User_Seek
, t.Last_User_Scan
, t.Last_User_Lookup
, t.Last_System_Seek
, t.Last_System_Scan
, t.Last_System_Lookup
from sys.dm_db_index_usage_stats as t
inner join sys.objects as obj on t.[object_id]=obj.[object_id]
inner join sys.indexes as ind on t.[object_id]=ind.[object_id] and t.index_id=ind.index_id
where (last_user_seek is null or last_user_seek 4 and t.[object_id]>0 --исключаются системные БД
Метки: author jobgemws администрирование баз данных ms sql server |
Дайджест KolibriOS #13 |
Между выпусками прошло достаточно много времени и накопилось достаточно изменений за 2017г.
Метки: author Siemargl системное программирование ненормальное программирование open source assembler kolibrios system programming |
[Перевод] Иллюзия скорости |
«Воспринимаемая производительность во многих случаях настолько же эффективна, как реальная производительность» (Basic Performance Tips)
Пока хлопальщик ближе 30 метров, вы слышите и видите хлопок одновременно. Но на большем расстоянии разница между скоростью света и скоростью звука превышает 80 миллисекунд, и мозг больше не может синхронизировать изображение со звуком. Самое странное, что переход резкий: буквально делая один шаг назад, хлопальщик выходит из синхронизации. Аналогично, пока саундтрек телепередачи или фильма синхронизирован с видеорядом в пределах 80 миллисекунд, вы не заметите никакого лага, но если задержка будет хоть немного больше, они резко и раздражающе разъединяются. События, которые заканчиваются быстрее чем за 80 миллисекунд, проходят незамеченными для сознания. Бьющий в бейсболе взмахивает битой по мячу прежде чем осознал, что питчер бросил его.
Когда мы извлекаем воспоминание из памяти, то одновременно перезаписываем его, так что в следующий раз при извлечении этого воспоминания мы получаем не оригинальную версию, а последнюю перезаписанную версию. Поэтому каждый раз, когда мы рассказываем историю, мы всё больше приукрашиваем её, оставаясь искренне убеждёнными в достоверности воспоминаний.
«Нужно 5 секунд для переключения каналов на ТВ»
«Этот парень сделал мне буррито за 5 секунд»
В 2004 году я посетил семинар “Redesigning Blogger”, где Джефф Вин из Adaptive Path и Дуглас Боуман из stopdesign.com (теперь в Twitter) обсуждали редизайн Blogger. Среди их наблюдений — то, что когда пользователи нажимали «Создать блог» на последнем этапе процесса установки, они были смущены тем, насколько быстро создаётся блог. «Это всё? Что-то не так?» — такого рода вопросы они задавали. Поэтому в процесс добавили промежуточный шаг — страницу «Создание блога…», которая ничего не делает, а только показывает маленький вращающийся gif, ожидая несколько секунд, прежде чем перенаправить новых пользователей на страницу «Ура, ваш блог создан!». Более длительным процессом пользователи стали гораздо довольнее.
Метки: author m1rko интерфейсы дизайн мобильных приложений графический дизайн веб-дизайн usability восприятие времени мозг индикатор загрузки |
Скрытый JS-майнинг криптовалюты на сайте: альтернатива рекламе или новая чума |
Буквально недавно промелькнула новость про Pirate Bay, который начал тестировать криптомайнер на JavaScript как альтернативу традиционной рекламной модели. Теперь же, судя по всему, нас ждет волна интеграции подобных скриптов в каждый мелкий магазинчик по продаже швейных принадлежностей. Только сегодня наткнулся на аналогичный скрипт, встроенный в код сайта zveruga.net — небольшой сети по продаже товаров для животных.
Сегодня позвонил отец и сообщил, что у него Kaspersky Total Security ругается на скрипт для майнинга на сайте зоомагазина. И даже успел безуспешно поругаться по этому поводу с девушкой на первой линии поддержки. С предсказуемым результатом "Эээээ… Чего? Скрипты?". Решил ради интереса проверить — вдруг ложная эвристика сработала. Оказалось, что вполне корректно сработало — в коде главной страницы http://www.zveruga.net/ нашлась странная вставка:
Кусок скрипта, активирующий майнинг оказался встроенным в блок Яндекс.Метрики. При активированном ghostery активности не проявлял, но стоило его временно отключить, как все ядра процессора немедленно нагружалось расчетами. Молодцы ребята из Mozilla. Теперь многопоточность!)
Сам по себе подобный майнинг крайне малоэффективен. Плюс требует наличия открытой вкладки со скриптом, что делает осмысленным интеграцию только на туда, где пользователь проводит действительно много времени. Pornhub не подойдет, да. Потому есть несколько вариантов:
В целом, мне кажется очень странным подобный способ получения прибыли. Сжирание процессора на 100% — это очень-очень грязный ход. Все же о таком следует предупреждать пользователя, который не ожидает такой подлости от браузера. В Kubuntu Linux тормоза интерфейса не ощущаются, видимо, из-за корректной приоритезации, а в Windows 7 система ощутимо начинает тупить. Немного страшно представить себе ситуацию, когда каждая вкладка начнет поедать системные ресурсы, пытаясь убить всех остальных.
В целом, вся эта фигня похожа на смесь очередной волны malware и поиска альтернативной модели заработка. Уже много клавиатур растоптано в сетевых баталиях на тему этичности блокировки рекламы. Вечная проблема столкновения интересов двух сторон — пользователь хочет качественный контент, создатель контента и сервиса хочет окупить свои затраты и немного заработать. И еще рекламные сети сбоку пристроились. С распространением блокировщиков рекламы ситуация становится все напряженнее. Кто-то уходит совсем, кто-то начинает показывать жалобных голодных котиков или переходить на модель платной подписки. Большинство тупо превращаются в сгенерированную копирайтерами за еду скриптами помойку с заголовками в духе Роспотребнадзор обвинил селфи в распространении вшей.
Возможность выкинуть на мороз рекламщиков крайне заманчиво выглядит для тех ресурсов, которых традиционно гнобят официальные власти — торрент-трекеры, продавцов неправильного укропа и тому подобные. Но и для обычных посещаемых ресурсов это может стать интересной альтернативой рекламной модели. Основные проблемы заключается в нескольких моментах:
Во все это безобразие уже включились антивирусы. С одной стороны, они вроде как на стороне огромной массы полуграмотных пользователей. С другой — что-то очень дофига они стали себе позволять в плане того, что может делать пользователь, а что нет, прорастая во все возможные часть операционной системы.
Кажется, нас ждет интересное ближайшее будущее. Ждем ответ от браузеров, блокирующих исполнение кода на неактивных вкладках. И еще очередного слоя блокировщиков. Единичные пользователи с радикальным NoScript вероятно опять пропустят все веселье.
Метки: author Meklon разработка веб-сайтов javascript monero реклама в интернете криптовалюта майнинг |
[Из песочницы] Разработка прибыльной Android игры двумя школьниками |
Метки: author Noobariouse разработка под android разработка мобильных приложений разработка игр программирование java android google play indie издание игр |
Еще один нюанс JavaScript, о котором все знают, но не все задумываются |
let a = {
'myKey': 'myValue'
}
let key = 'constructor'; // comes from outside source
let b = a[key] || 'defaultValue';
expect(b).to.be.equal('defaultValue'); // fails
const result = {};
for (var prop of Object.getOwnPropertyNames(Object.prototype)) {
result[prop] = undefined;
}
return result;
// file1
export function myFunction(){}
// file2
export class myClass{}
export * from './file1';
export * from './file2';
//было
import { myFunction } from './folder/file1';
import { myClass } from './folder/file2';
//стало
import { myFunction, myClass } from './folder';
import { myClass } from '.';
export function myFunction(){ // doSmth with class }
Метки: author VladVR javascript typescript |
Дайджест интересных материалов для мобильного разработчика #222 (18 — 24 сентября) |
![]() |
Как работает Android, часть 2 |
![]() |
Руководство по выживанию в Steam для мобильных разработчиков |
|
[Из песочницы] ViewModel и LiveData: паттерны и антипаттерны |
ViewModel (и Presenter) не должны знать о классах фреймворка Android
Активити и фрагменты должны содержать минимум логики
Избегайте ссылок на View в ViewModels.Рекомендуемый способ коммуникации между ViewModel и View — использование observer pattern, при помощи LiveData или observable из других библиотек.
private void subscribeToModel() {
// Observe product data
viewModel.getObservableProduct().observe(this, new Observer() {
@Override
public void onChanged(@Nullable Product product) {
mTitle.setText(product.title);
}
});
}
Вместо того, чтобы отсылать данные в UI, пусть UI наблюдает за изменениями в данных.
Распределяйте ответственности, добавьте слой domain если требуется.
Добавьте репозиторий данных в качестве едсинственной точки входа для данных
Expose информацию о состоянии данных, используя обертку или другой LiveData.
LiveData snackbarMessage = new MutableLiveData<>();
snackbarMessage.setValue("Объект сохранен!");
Для таких событий, как показ сообщений в Snackbar или навигации используетй observable вроде SingleLiveEvent.
Учитывайте пограничные случаи, утечки памяти и то, как долгие операции может повлиять на инстансы в Вашей архитектуре.
Не помещайте в ViewModel логику, которая является критически важной для сохранения чистоты архитектуры или если она связана с данными. Каждый вызов, сделанный от ViewModel может быть последним.
LiveData repo = Transformations.switchMap(repoIdLiveData, repoId -> {
if (repoId.isEmpty()) {
return AbsentLiveData.create();
}
return repository.loadRepo(repoId);
}
);
Каждый раз, когда Вы думаете, что Вам нужен объект Lifecycle внутри ViewModel, использование Transformation скорее всего поможет этого избежать и решит проблему.
public class MyLiveData extends LiveData {
public MyLiveData(Context context) {
// Initialize service
}
@Override
protected void onActive() {
// Start listening
}
@Override
protected void onInactive() {
// Stop listening
}
}
Обычно наследование от LiveData не происходит. Пусть активити или фрагмент подскажет ViewModel когда начать загружать данные.Оригинал статьи
Метки: author artem_dobrovinskiy разработка под android android livedata antipatterns перевод |
IMaskjs — простое маскирование в браузере |
var numberMask = new IMask(inputElement, {
mask: Number,
min: -10000,
max: 10000,
thousandsSeparator: ' '
});
var dateMask = new IMask(inputElement, {
mask: Date,
min: new Date(2000, 0, 1),
max: new Date(2020, 0, 1),
placeholder: {lazy: false}
});
var groupsMask = new IMask(inputElement, {
mask: '19YY.MM.DD',
// описание групп
groups: {
// общее описание группы
YY: {
mask: '00',
// возможно использование валидатора
// validate: function (value, group) {}
},
// но можно создавать группы из интервала значений или перечислений
MM: new IMask.MaskedPattern.Group.Range([1, 12]),
DD: new IMask.MaskedPattern.Group.Range([1, 31])
}
});
Метки: author burfee разработка веб-сайтов javascript imaskjs ввод текста форматирование маска jquery inputmask |
Как на анимешниках криптовалюту добывают |
Метки: author unc1e информационная безопасность аниме майнеры monero криптовалюта javascript iframe |
Типичное использование Observable объектов в Angular 4 |
Представляю вашему вниманию типичные варианты использования Observable объектов в компонентах и сервисах Angular 4.
Задача: При открытии страницы example.com/#/users/42
, по userId
получить данные пользователя.
Решение: При инициализации компоненты UserDetailsComponent
мы подписываемся на параметры роутера. То есть если userId
будет меняться — будер срабатывать наша подписка. Используя полученный userId
, мы из сервиса userService
получаем Observable
с данными пользователя.
// UserDetailsComponent
ngOnInit() {
this.route.params
.pluck('userId') // получаем userId из параметров
.switchMap(userId => this.userService.getData(userId))
.subscribe(user => this.user = user);
}
Задача: При открытии страницы example.com/#/users/42?regionId=13
нужно выполнить функцию load(userId, regionId)
. Где userId
мы получаем из роутера, а regionId
— из параметров запроса.
Решение: У нас два источника событий, поэтому воспользуемся функцией Observable.combineLatest, которая будет срабатывать, когда каждый из источников генерирует событие.
ngOnInit() {
Observable.combineLatest(this.route.params, this.route.queryParams)
.subscribe(([params, queryParams]) => { // полученный массив деструктурируем
const userId = params['userId'];
const regionId = queryParams['regionId'];
this.load(userId, regionId);
});
}
Обратите внимание, что созданные подписки на роутер, при разрушении объекта удалятся, за этим следит ангуляр, поэтому отписываться от параметров роутера не нужно:
The Router manages the observables it provides and localizes the subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against memory leaks, so we don't need to unsubscribe from the route params Observable. Mark Rajcok
Задача: Показать значок загрузки после начала сохранения данных и скрыть его, когда данные сохранятся или произойдет ошибка.
Решение: За отображение загрузчика у нас отвечает переменная loading
, после нажатия на кнопку, установим ее в true
. А для установки ее в false
воспользуемся Observable.finally
функций, которая выполняется после завершения подписки или если произошла ошибка.
save() {
this.loading = true;
this.userService.save(params)
.finally(() => this.loading = false)
.subscribe(user => {
// Успешно сохранили
}, error => {
// Ошибка сохранения
});
}
Задача: Создать переменную lang$
в configService
, на которую другие компоненты будут подписываться и реагировать, когда язык будет меняться.
Решение: Воспользуемся классом BehaviorSubject
для создания переменной lang$
;
Отличия BehaviorSubject
от Subject
:
BehaviorSubject
должен инициализироваться с начальным значением;Subject
а;getValue()
.Создаём переменную lang$
и сразу инициализируем. Так же добавляем функцию setLang
для установки языка.
// configService
lang$: BehaviorSubject = new BehaviorSubject(DEFAULT_LANG);
setLang(lang: Language) {
this.lang$.next(this.currentLang); // тут мы поставим
}
Подписываеся на изменение языка в компоненте. Переменная lang$
является "горячим" Observable объектом, то есть подписка требует отписки при разрушении объекта.
private subscriptions: Subscription[] = [];
ngOnInit() {
const langSub = this.configService.lang$
.subscribe(() => {
// ...
});
this.subscriptions.push(langSub);
}
ngOnDestroy() {
this.subscriptions
.forEach(s => s.unsubscribe());
}
Отписываться можно и более изящным вариантом, особенно если в компоненте присутствует больше двух подписок:
private ngUnsubscribe: Subject = new Subject();
ngOnInit() {
this.configService.lang$
.takeUntil(this.ngUnsubscribe) // отписка по условию
.subscribe(() => {
// ...
});
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
То есть, чтобы не терять память на горячих подписках, компонента будет работать до тех пор, пока значение ngUnsubscribe
не изменится. А изменится оно, когда вызовется ngOnDestroy
. Плюсы этого варианта в том, что в каждую из подписок достаточно добавить всего одну строчку, чтобы отписка сработала вовремя.
Задача: Показывать предложения страниц при вводе данных на форме
Решение: Подпишемся на изменение данных формы, возьмём только меняющиеся данные инпута, поставим небольшую задержку, чтобы событий не было слишком много и отправим запрос в википедию. Результат выведем в консоль. Интересный момент в том, что switchMap
отменит предыдущий запрос, если пришли новые данные. Это очень полезно, для избегания нежалательных эффектов от медленных запросов, если, к например, предпоследний запрос выполнялся 2 секунды, а последий 0.2 секунды, то в консоль выведется результат именно последнего запроса.
ngOnInit() {
this.form.valueChanges
.takeUntil(this.ngUnsubscribe) // отписаться после разрушения
.map(form => form['search-input']) // данные инпута
.distinctUntilChanged() // брать измененные данные
.debounceTime(300) // реагировать не сразу
.switchMap(this.wikipediaSearch) // переключить Observable на запрос в Вики
.subscribe(data => console.log(data));
}
wikipediaSearch = (text: string) => {
return Observable
.ajax('https://api.github.com/search/repositories?q=' + text)
.map(e => e.response);
}
Задача: Необходимо закешировать Observable запрос
Решение: Воспользуемся связкой publishReplay
и refCount
. Первая функция закеширует одно значение функции на 2 секунды, а вторая будет считать созданные подписки. То есть, Observable завершится, когда все подписки будут выполнены. Тут можно прочитать подробнее.
// tagService
private tagsCache$ = this.getTags()
.publishReplay(1, 2000) // кешируем одно значение на 2 секунды
.refCount() // считаем ссылки
.take(1); // берем 1 значение
getCachedTags() {
return tagsCache$;
}
Задача: Критическая ситуация на сервере! Backend команда сообщила, что для корректного обновления продукта нужно выполнять строго последовательно:
Решение: У нас есть 3 Observable, полученных из productService
. Воспользуемся concatMap
:
const updateProduct$ = this.productService.update(product);
const updateTags$ = this.productService.updateTags(productId, tagList);
const updateCategories$ = this.productService.updateCategories(productId, categoryList);
Observable
.from([updateProduct$, updateTags$, updateCategories$])
.concatMap(a => a) // выполняем обновление последовательно
.toArray() // Возвращает массив из последовательности
.subscribe(res => console.log(res)); // res содержит массив результатов запросов
Если у вас есть желание немного поупражняться, решите предыдущую задачу, но для создания продукта. То есть сначала создаём продукт, потом обновляем теги, а только потом — категории.
Метки: author lucius разработка веб-сайтов программирование javascript angularjs angular 4 observable rxjs typescript rxjs5 |
Баг или фича в Facebook Messenger — Опрос |
Метки: author Ehuhaa системы обмена сообщениями информационная безопасность facebook messenger |
[Из песочницы] Cоздаём компонент карт Google Maps API с помощью VueJs2 |
export default {
name: 'google-map',
props: ['name'],
data: function () {
return {
map: ''
}
},
computed: {
mapMarkers: function () {
return this.markers
}
},
mounted: function () {
const element = document.getElementById(this.name)
const options = {
zoom: 14,
center: new google.maps.LatLng(59.93, 30.32)
}
this.map = new google.maps.Map(element, options)
},
methods: {}
}
data: function () {
return {
map: '',
markers: [
{
position: {
latitude: 59.93,
longitude: 30.32
}
},
{
position: {
latitude: 59.928,
longitude: 30.32
}
}
]
}
}
mounted: function () {
const element = document.getElementById(this.name)
const options = {
zoom: 14,
center: new google.maps.LatLng(59.93, 30.32)
}
this.map = new google.maps.Map(element, options)
this.markers.forEach((marker) => {
const position = new google.maps.LatLng(marker.position.latitude, marker.position.longitude)
marker.map = this.map
marker.position = position
new google.maps.Marker(marker)
})
}
Метки: author BRAINKIT javascript vuejs2 es6 |
Лекция Илья Сегаловича «Как создать компанию — мирового лидера?» |
Метки: author Leono управление разработкой развитие стартапа карьера в it-индустрии бизнес-модели блог компании яндекс илья сегалович яндекс 80- 90- стартап опыт |
[Из песочницы] Кто, как и зачем собирается регулировать Big Data в России? |
Готовы предоставить комментарий с анализом и прогнозом по законопроекту о регулировании Big Data будет, который будет готов к концу 2017 года.
Медиа-Коммуникационный союз (МКС) к концу 2017 года представит законопроект, в том числе регулирующий использование «больших» пользовательских данных (Big Data), рассказал РИА Новости глава Роскомнадзора Александр Жаров
одним из итогов собрания, зафиксированных в его протоколе, стал довольно длинный список предложений, как наше государство может использовать большие данные на благо общественного развития. Проблем же собственно больших данных с точки зрения необходимости их нормативного регулирования выявлено не было.
Метки: author akolesov законодательство и it-бизнес big data |
[Перевод] Go: 10 лет и растём дальше |
На этой неделе мы отмечаем 10-летнюю годовщину создания Go.
Всё началось с обсуждения вечером в четверг, 20 сентября 2007. Оно привело к организованной встрече между Робертом Грисмайером, Робом Пайком и Кеном Томпсоном в 2 часа дня на следующий день в конференс-руме Yaounde в Здании 43 главного кампуса Google Mountain View. Название для языка появилось 25-го числа, несколько сообщений спустя после начала переписки о дизайне:
Тема: Re: обсуждение языка программирования
От: Роб 'Коммандер' Пайк
Дата: Вт, Сен 25, 2007 в 3:12 PM
Кому: Роберт Грисмайер, Кен Томпсон
у меня возникло пару мыслей по этому поводу на пути домой.
1. имя
'go'. можно найти оправдания для такого имени, но у него очень хорошие свойства.
оно короткое, легко печатать, например: goc, gol, goa. если будет интерактивный
дебаггер/интерпретатор, он может быть просто назван 'go'. расширение файла .go
...
(Следует отметить, что язык называется Go; "golang" происходит от названия сайта (go.com был уже занят компанией Disney), но это не есть правильное название языка)
Днем Рождения проекта Go официально является 10 ноября 2009 — день, когда проект был открыт open-source миру, сначала на code.google.com, перед тем как мигрировал на Github несколько лет позднее. Но сейчас давайте считать дату рождения от фактического рождения языка, двумя годами ранее, что позволит нам заглянуть глубже в прошлое, увидеть более полную картину и стать свидетелями некоторых более ранних событий из истории Go.
Первым большим сюрпризом в разработке Go было получение вот этого письма:
Тема: Фронтенд gcc для Go
От: Ян Ленс Тэйлор
Дата: Сб, Июнь 7, 2008 в 7:06 PM
Кому: Роберт Грисмайер, Роб Пайк, Кен Томпсон
Один из моих коллег показал мне http://.../go_lang.html .
Выглядит очень интересным языком и я сделал gcc фронтенд
к нему. Понятно, там ещё много чего не хватает, но он может
скомпилировать код для решета Эратосфена с главной страницы.
Неожиданное, но восхитительное прибытие нового союзника (Яна) и второго компилятора (gccgo) было не просто вдохновляющим, оно было решаюшим. Появление второй реализации языка было критичным для процесса формализации спецификации и библиотек, усиливая гарантию того, что портабельность языка является частью обещания о совместимости.
Несмотря на то, что его офис был не так далеко, мы никогда не встречались с Яном ранее, но с тех пор он стал центральным игроком в дизайне и реализации языка и его инструментария.
Расс Кокс присоединился к зарождающейся команде Go тоже в 2008-м, принеся массу свежих трюков с собой. Расс открыл — и это именно подходящее слово — что обобщённая природа методов в Go означает, что функции тоже могут иметь методы, что привело к появлению http.HandlerFunc, что было очень неожиданно для нас всех. Расс родил и другие интересные идеи, вроде io.Reader и io.Writer интерфейсов, которые сформировали структуру всех I/O библиотек.
Джини Ким, которая была нашим продакт менеджером вначале, наняла специалиста по безопасности Адама Лангли, чтобы помочь нам запустить Go в мир. Адам сделал огромное количество вещей, которые не сильно широко известны, включая создание первой версии сайта golang.org и дашборда сборки, но, конечно, главным его вкладом были криптографические библиотеки. Поначалу они казались непропорционально большими и по размеру и по сложности, по крайней мере для многих из нас, но они стали фундаментом для столь большого количества сетевого и криптографического кода, что стали ключевой частью истории Go. Сетевые инфраструктурные компании вроде Cloudflare зависят очень сильно от работ Адама в Go, и интернет благодаря ним стал лучше. Равно как и Go, за что огромная благодарность Адаму.
На самом деле, много компаний стали играть с Go на очень ранних этапах, в частности стартапы. Некоторые из них стали ядрами для облачных инфраструктур. Один из таких стартапов, сейчас называющийся Docker, использовал Go и послужил катализатором индустрии компьютеров, что затем привело к таким проектам как Kubernetes. Сегодня можно смело утверждать, что Go это язык для контейнеров, ещё один совершенно неожиданный результат.
Роль Go в облачной экосистеме на самом деле даже больше. В марте 2014 Donnie Berkholz, в статье для RedMonk, написал, что Go был "появляющимся языком для облачной инфраструктуры". Примерно в тоже время Derek Collision из Apcera указал, что Go был уже языком для облака. Это могло быть ещё не так истинно в те дни, но как слово "появляющийся" и указывало, это становилось всё более истинно.
Сегодня Go это язык для софта в облаке, и одна мысль о том, что язык, которому всего 10 лет, стал доминирующим в такой большой и быстрорастущей индустрии это успех, о котором можно только мечтать. И если вам кажется, что "доминирует" это слишком сильное слово, посмотрите на интернет внутри Китая. Какое то время, высокая популярность Go в Китае, показываемая Google trends намекала на какую-то ошибку, но каждый, кто был хоть раз на Go конференциях в Китае, понимает, что эта популярность реальна. Go невероятно популярен в Китае.
Если кратко, то за 10 лет пути с Go мы прошли много ключевых точек. Одна из самых поразительных в нашем текущем положении — скромная оценка указывает, что в мире примерно пол миллиона Go программистов. Когда первое письмо с предложением имени Go было отправлено, мысль о том, что вскоре будет пол миллиона гоферов показалась бы абсурдом. И вот мы тут, и это количество продолжает только расти.
Говоря о гоферах, это было забавно наблюдать, как идея маскота Рене Френч — гофер Go — стала не только самым излюбленным созданием, но и символом Go программистов по всему миру. Многие из крупнейших Go конференций называются GopherCons, так как собирают гоферов со всего мира.
Конференции гоферов только начинаются. Первая была проведена 3 года назад, но сейчас их уже множество по всему миру, плюс бесчисленные локальные "митапы". В любой день есть большой шанс что где-то в мире происходит встреча гоферов для обмена идеями.
Оглядываясь на 10 лет назад дизайна и разработки Go, отдельно поражает рост Go сообщества. Количество конференций и митапов, длинный и всё увеличивающийся список людей, участвующих в разработке Go, изобилие open source репозиториев с Go кодом, количество компаний, использующих Go, некоторые из которых используют исключительно Go: это просто изумительно наблюдать.
Для нас троих, Роберта, Роба и Кена, которые просто хотели сделать наши программисткие будни чуть легче, доставляет невероятное удовольствие наблюдать, что наш проект запустил в жизнь.
Что принесут следующие 10 лет?
Метки: author divan0 go golang |