• Как перейти на другую версию go?

    Зачем вам go на сервере? Деплойте туда уже собранные бинарники и нет проблем.
    Соберите бинарь аппликухи на go 1.3 и на go 1.6. Если с 1.6 не пойдет, просто запустите старый бинарь с 1.3.
    Ответ написан
    Комментировать
  • Как найти узкие места?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    гугл гугл гугл гугл гугл гугл гугл гугл гугл гугл
    https://habrahabr.ru/company/badoo/blog/301990/
    Ответ написан
    3 комментария
  • Что почитать о гейм деве?

    AtomKrieg
    @AtomKrieg
    Давай я поищу в Google за тебя
    Тут архитектура
    gameprogrammingpatterns.com
    Тут алгоритмы поиска пути
    www.redblobgames.com
    Ответ написан
    2 комментария
  • Высоконагруженные системы, каковы принципы разработки?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    давайте так, есть два вида задач:

    - CPU bound - различные алгоритмы, математика, кодирование/декодирование/шифрование... словом все что нагружает процессор.
    - I/O bound - собственно когда у нас идет множество операций с вводом/выводом, где-то 90% задач связанных с WEB и серверной разработкой.

    Для CPU bound стоит использовать языки вроде Си, Rust, Dlang, Go и т.д. Словом языки которые компилируются в эффективный машинный код.

    Для I/O bound - Go, NodeJS, Erlang, Java.... да в принципе не важно какой язык, главное что бы использовались неблокируемые вызовы и отсутствовали блокировки.

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

    Какие языки лучше использовать для этого? Какие не использовать?

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

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

    И на таких объемах даже если бы мы взял Си, если наш алгоритм имеет сложность O(N^2) то как бы ничего тут особо не поделать. И так и так медленно будет. А вот если мы возьмем какие-либо алгоритмы имеющие сложность O(NLogN) то уже возможно что алгоритм этот можно хоть на php/python/ruby имплементить. Так например у меня этот алгоритм реализован на Java и не самым эффективным образом. Справляется.

    Еще влияет скорость разработки (всякие ruby/python/node в этом плане хороши), стоимость поддержки (Си поддерживать сильно дороже чем Go например, хотя всегда можно написать все настолько плохо что проще выкинуть чем поддерживать), стоимость разработчиков.... Скажем найти дешевых сильных разработчиков на Go или Rust будет весьма проблематично.

    Так же не стоит забывать что сервера нынче стоят не так дорого. Иногда бизнесу проще доплатить за еще десяток серверов нежели писать все на плюсах.

    Собственно главное правило высоконагруженных систем - нагрузочное тестирование а потом уже оптимизации
    Ответ написан
    Комментировать
  • Зачем в языке Go приняты отступы в 8 символов?

    Там не 8 символов, там tab. Вы можете настроить в вашем текстовом редакторе размер табуляции в нужное вам количество символов.
    Ответ написан
    Комментировать
  • Как переиспользовать net.Connect?

    @lucifer-m Автор вопроса
    golang php js html css
    Я так и не понял почему заработало....
    сервер
    package server
    
    import (
    	"bufio"
    	"fmt"
    	"io"
    	"net"
    	"os"
    )
    
    func Run(host string, port string, handle func(data string) string) {
    	l, err := net.Listen("tcp", host+":"+port)
    	if err != nil {
    		fmt.Println("Error listening:", err.Error())
    		os.Exit(1)
    	}
    	defer l.Close()
    	fmt.Println("Слушает " + host + ":" + port)
    	for {
    		conn, err := l.Accept()
    		if err != nil {
    			fmt.Println("Ошибка запуска: ", err.Error())
    			os.Exit(1)
    		}
    		go handleRequest(conn, handle)
    	}
    }
    
    func handleRequest(conn net.Conn, handle func(data string) string) {
    	fmt.Println("handleRequest")
    	var (
    		buf = make([]byte, 1024)
    		r   = bufio.NewReader(conn)
    		w   = bufio.NewWriter(conn)
    	)
    ILOOP:
    	for {
    		n, err := r.Read(buf)
    		data := string(buf[:n])
    		switch err {
    		case io.EOF:
    			break ILOOP
    		case nil:
    
    			if string(data) == "ConnectionClose" {
    				fmt.Println("Соединение закрыто")
    				w.WriteString("ConnectionClose\r\n")
    				w.Flush()
    				conn.Close()
    			} else {
    				w.WriteString(handle(data) + "\r\n")
    				w.Flush()
    				//break ILOOP
    			}
    
    		default:
    			fmt.Println("Ошибка при получении:", err)
    			break ILOOP
    		}
    	}
    
    }

    клиент
    package client
    
    import (
    	"bufio"
    	"fmt"
    	"io"
    	"net"
    	"strings"
    )
    
    type TcpClient struct {
    	r    *bufio.Reader
    	w    *bufio.Writer
    	buf  []byte
    	conn net.Conn
    }
    
    func Connect(host string, port string) (TcpClient, error) {
    	fmt.Println("Connect")
    	conn, err := net.Dial("tcp", host+":"+port)
    	return TcpClient{
    		buf:  make([]byte, 1024),
    		r:    bufio.NewReader(conn),
    		w:    bufio.NewWriter(conn),
    		conn: conn,
    	}, err
    }
    
    func (tcp TcpClient) Send(dataSend string) (string, error) {
    	var (
    		returnData string
    		returnErr  error
    	)
    	tcp.w.WriteString(dataSend + "\r\n")
    	tcp.w.Flush()
    ILOOP:
    	for {
    		n, err := tcp.r.Read(tcp.buf)
    		data := string(tcp.buf[:n])
    		switch err {
    		case io.EOF:
    			break ILOOP
    		case nil:
    			returnData = data
    			returnErr = nil
    			if isTransportOver(data) {
    				break ILOOP
    			}
    		default:
    			returnData = ""
    			returnErr = err
    		}
    	}
    	return returnData, returnErr
    }
    func (tcp TcpClient) Close() {
    	tcp.conn.Close()
    }
    
    func isTransportOver(data string) (over bool) {
    	over = strings.HasSuffix(data, "\r\n")
    	return
    }
    Ответ написан
    Комментировать
  • Как переиспользовать net.Connect?

    @FireGM
    Потому что tcp.Close() закрывает соединение.
    Ответ написан
    1 комментарий
  • Как реализовать модульность?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Golang по умолчанию компилируется в 1 бинарь. Да, можно подключать shared либы, да можно собирать, но язык заточен не под это.
    Что бы подключать функционал - гуглите на тему "golang unsafe", "golang load dynamic library". Но вообще говоря - это со всей силы не golang-way.

    каждый модуль использовать как микросервис

    вполне вариант

    представить не могу как расширить функцию парсинга команд

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

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

    [client] <-??-> [client-app] <-rpc|queue|...-> [main-server] <-rpc|queue|...=>[modules]
    Ответ написан
    5 комментариев
  • Как распредилить диапазон ip?

    @lucifer-m Автор вопроса
    golang php js html css
    Спасибо Никита. Немного переделав ваш пример я получил то что хотел.
    package main
    
    import (
    	"fmt"
    	"net"
    )
    
    func inet_aton(ip string) (ip_int uint32) {
    	ip_byte := net.ParseIP(ip).To4()
    	for i := 0; i < len(ip_byte); i++ {
    		ip_int |= uint32(ip_byte[i])
    		if i < 3 {
    			ip_int <<= 8
    		}
    	}
    	return
    }
    
    func inet_ntoa(ip uint32) string {
    	return fmt.Sprintf("%d.%d.%d.%d", byte(ip>>24), byte(ip>>16), byte(ip>>8),
    		byte(ip))
    }
    
    
    func main() {
    	ip0 := inet_aton("127.0.0.1")
    	ip1 := inet_aton("127.225.225.224")
    	
    	
    	diff := ip1 - ip0
    	var parts uint32 = 30
    	step := diff/parts 
    	
    	var ippps string = "0"
    	for i := uint32(0); i < parts; i++ {
    		//вместо принта шлю зону ботам
    		if ippps != "0"{
    			fmt.Println(ippps+"-"+inet_ntoa(ip0 + step*i))
    		}
    	        ippps = inet_ntoa(ip0 + step*i)
    	}
    	
    }
    Ответ написан
    Комментировать
  • Как, в go, определить тип интерфейса который тип структ?

    @Maxim_Samburskiy
    К сожалению, это невозможно, v является синонимом TEST, но при компиляции создаётся два типа структур: v и TEST.
    Ответ написан
    1 комментарий
  • Как, в go, определить тип интерфейса который тип структ?

    uvelichitel
    @uvelichitel Куратор тега Go
    habrahabr.ru/users/uvelichitel
    Это потому что вы ссылку разбираете
    i := interface{}(&v{})
    	t := reflect.TypeOf(i).Name()
    	fmt.Println("type:",t)

    вы или передайте value
    i := interface{}(v{})
    t := reflect.TypeOf(i).Name()

    или разыменовывайте
    i := interface{}(&v{})
    t := reflect.TypeOf(i).Elem().Name()

    тогда заработает https://play.golang.org/p/BUkX1zQICH
    Ответ написан
    3 комментария
  • Как записать в переменную большую строку с помощью fmt.Scan ??

    bitver
    @bitver
    var s string
    fmt.Scanf("%q", &s)
    
    // Или
    
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        s := scanner.Text()
        fmt.Println(s)
    }
    Ответ написан
    1 комментарий
  • Попросили проверить код, на что смотреть нужно?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Смотря зачем)). Я когда делаю Code Review критерии следующие:

    * Безопасность:
    - Каждый аргумент метода простого типа должен проверяться на тип в случае его проксирования и на граничные значения в случае обработки. Чуть что не так - бросается исключение. Если метод с кучкой аргументов на 80% состоит из поверки из аргументов - это вполне норм))
    - Никаких trigger_error, только исключения.
    - Исключения ДОЛЖНЫ быть человеко-понятны, всякие "Something went wrong" можно отдавать пользователю, но в лог должно попасть исключение со стектрейсом и человеко-понятным описанием, что же там пошло не так.
    - Каждый аргумент (объект) метода должен быть с тайпхинтингом на этот его класс, или интерфейс.
    - За eval как правило шлю на **й.
    - @ допускается только в безвыходных ситуациях, например проверка json_last_error.
    - Перед работой с БД - обязательная проверка данных.
    - Никаких == и !=. Со swtich - единственное исключение, по ситуации.
    - Если метод возвращает не только bool, а еще что-то - жесткая проверка с ===, или !== обязательна.
    - Никаких условий с присваиваниями внутри. while($row = ...) - тоже идет лесом.
    - Магические геттеры/сеттеры разрешаются только в безвыходных ситуациях, в остальном - запрещены.
    - Конкатенации в sql - только в безвыходных ситуациях.
    - Параметры в sql - ТОЛЬКО через плейсхолдеры.
    - Никаких глобальных переменных.
    - Даты в виде строки разрешаются только в шаблонах и в БД, в пхп коде сразу преобразуется в \DateTimeImmutable (в безвыходных ситуациях разрешено \DateTime)
    - Конечно зависит от проекта, но как приавло должно быть всего две точки входа: index.php для web и console(или как-то по другому назваться) - для консоли.

    * Кодстайл PSR-2 + PSR-5 как минимум, + еще куча более жестких требований (для начала все то что в PSR помечено как SHOULD - становится MUST)
    - В PhpStorm ни одна строчка не должна подсвечиваться (исключением является typo ошибки, например словарик не знает какой-то из аббревиатур, принятых в вашем проекте). При этом разрешается использовать /** @noinspection *** */ для безвыходных ситуаций.
    - Если кто-то говорит, что пишет в другом редакторе и у него не подсвечивается, на эти отговорки кладется ВОТ ТАКЕЕЕНЫЙ мужской половой **й и отправляется на доработку)).

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

    * Тестируемость (в смысле простота тестирования) кода должна быть высокая.
    - Покрытие кода обязательно для всех возможных кейсов использования каждого публичного метода с моками зависимостей.

    * Принципы MVC:
    - Никаких обработок пользовательского ввода в моделях, от слова совсем.
    - Никаких ***ть запросов в БД из шаблонов.
    - Никаких верстки/js/css/sql-ин в контроллерах.
    - В моделях НИКАКОЙ МАГИИ, только приватные свойства + геттеры с сеттерами.
    - В моделях разрешено использовать метод save(при наличии такого разумеется) только в исключительных ситуациях. Во всех остальных - либо insert, либо update.

    * Принципы SOLD:
    - Никаких божественных объектов умеющих во все.
    - Если метод для внутреннего пользования - private, никаких public.
    - Статические методы разрешаются только в случае безвыходности.

    * Принцип DRY разрешено нарушать в случаях:
    - Явного разделения обязанностей
    - В тестах (каждый тест должен быть независимым, на сколько это возможно)

    * Работа с БД:
    - Запрос в цикле должен быть РЕАЛЬНО обоснован.
    - За ORDER BY RAND() - шлю на***й.
    - Поиск не по ключам (конечно если таблица НЕ на 5 строк) запрещен.
    - Поиск без LIMIT (опять же если таблица НЕ на 5 строк) запрещен.
    - SELECT * - запрещен.
    - Денормализация БД должна быть обоснована.
    - MyISAM не используется (так уж)) )
    - Множественные операции обязательно в транзакции, с откатом если чо пошло не так.
    - БД не должна содержать бизнес логики, только данные в целостном виде.
    - Не должно быть нецелесообразного дерганья БД там, где без этого можно обойтись.

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

    * О людях:
    - "Я привык писать так и буду дальше" - не вопрос, ревью пройдешь только когда поменяешь свое мнение.
    - "Я пишу в vim-е и мне так удобно" - здорово, код консолью я тоже в нем пишу)) но есть требования к коду, если в них не сможешь - не пройдешь ревью.
    - "Я скопировал этот страшный метод и поменял 2 строчки" - это конечно замечательно, но по блейму автор всего этого метода ты, так что давай без говняшек, хорошо?
    - "Оно же работает!" - вот эта фраза переводится примерно так: "да, я понимаю, что пишу полную хрень, но не могу писать нормально потому, что руки из жо", я правильно тебя понял?))
    - "У меня все работает!" - рад за тебя, а как на счет продакшна?
    - "Там все просто" - не используй слово "просто", от слова "совсем". Вот тебе кусок кода (первого попавшегося с сложной бизнес логикой), где там ошибка (не важно есть она, или нет)? Ты смотришь его уже 2 минуты, в чем проблема, там же все "просто"))

    * Всякое:
    ActiveRecord (это я вам как в прошлом фанат Yii говорю) - полное говно, примите за исходную. По факту у вас бесконтрольно по проекту гуляют модельки с подключением к БД. Не раз натыкался на то, что в тех же шаблонах вызывают save, или update (за такое надо сжигать).
    То, что используется Laravel - это печально((. Что бы выполнить требования приведенные выше, приходится "воевать" с фреймворком.

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

    UPD

    Формализировал данные критерии по ссылочке: https://github.com/index0h/php-conventions
    Ответ написан
    55 комментариев
  • Есть ли в данный момент крупные проекты, где применяется язык Go?

    @abcyu
    Разработчик
    В чем у Вас сомнения? Go уже много лет как в production у серьезных фирм.

    Google
    Docker
    Mozilla
    Canonical
    Facebook (for Parse)
    Dropbox
    BBC
    Iron.io
    37signals
    SoundCloud
    CloudFlare

    и др.......
    Ответ написан
    8 комментариев
  • Почему type []User нельзя использовать как type []UserInterface?

    Tyranron
    @Tyranron
    Это сделано намеренно, дабы избежать неявных дорогих преобразований.

    Первое, что нужно знать — это отличия «структуры» от «интерфейса» в Go. Это просто, и этого достаточно, чтобы понять, почему вы просто так не можете «скастить» слайс структур в слайс интерфейсов.
    ...
    Второе — и созвучное с выше обсужденными слайсами — это то, операция конвертирования слайсов — дорогая операция. По времени это O(n) и компилятор Go подобные дорогие вещи не будет делать, чтобы не давать нерадивым программистам писать медленный код. Хотите делать потенциально дорогую операцию — будьте добры, сделайте это явно, вся ответственность на вас, а не на компиляторе.

    Детальнее:
    Холиворная статья: причина №4
    Объяснение на SO
    Ответ написан
    Комментировать
  • Как создать нового пользователя в Debian?

    artemn
    @artemn
    Senior PHP Developer
    [debian]
    adduser --home /var/www --shell /bin/false --ingroup ftp USERNAME

    --home /var/www — задать home директорию
    --shell /bin/false — если запретить выполнение баша
    --ingroup ftp — поселить юзверя в группу
    etc.

    а вообще
    adduser  [options]  [--home  DIR]  [--shell  SHELL]  [--no-create-home]
           [--uid ID] [--firstuid ID] [--lastuid ID] [--ingroup GROUP | --gid  ID]
           [--disabled-password]      [--disabled-login]      [--gecos      GECOS]
           [--add_extra_groups] user

    ИМХО, четко описывает.
    Ответ написан
    Комментировать
  • Git hooks (bare). Как узнать имя ветки в которую был внесен последний коммит?

    DevMan
    @DevMan
    Пример post-update хука:
    #!/bin/bash
    
    branch=`git rev-parse --symbolic --abbrev-ref $1`
    echo "Pushed to branch '$branch'"
    exec git update-server-info
    
    Ответ написан
    1 комментарий
  • Go IDE

    evilbloodydemon
    @evilbloodydemon
    Sublime Text + GoSublime + Gocode мне пока что кажутся лучшим вариантом. Заработало сразу после установки — билд, полный автокомплит, автоформат и даже отображение ошибок в редакторе.
    Хотя полноценную IDE хотелось бы, да.
    Ответ написан
    2 комментария
  • Какими цветами вы подсвечиваете ваш код на C?

    appplemac
    @appplemac
    Sublime Text 2, тема Monokai Bright
    Ответ написан
    Комментировать