Свежие статьи:
- Go 2018 Survey Results https://blog.golang.org/survey2018-results
- Debugging what you deploy in Go 1.12 https://blog.golang.org/debugging-what-you-deploy (от https://twitter.com/Dr2chase)
- Go 2018 Survey Results https://blog.golang.org/survey2018-results
- Debugging what you deploy in Go 1.12 https://blog.golang.org/debugging-what-you-deploy (от https://twitter.com/Dr2chase)
Twitter
David Chase (@Dr2chase) | Twitter
The latest Tweets from David Chase (@Dr2chase). Not a physician, bikes a lot, DFH, works on Go compiler.
He/him. Ex(?) Florida Man.
(I do not speak for my employer. near Boston, MA
He/him. Ex(?) Florida Man.
(I do not speak for my employer. near Boston, MA
Вот как нужно делать программу для конференции!
GoCon Canada -> https://play.golang.org/p/dSlNFqsiKKl
GoCon Canada -> https://play.golang.org/p/dSlNFqsiKKl
Наверное одна из самых лучших статей, которые попадались мне на тему как писать хороший Git Commit Message https://chris.beams.io/posts/git-commit/
Чистый код только в контексте Го https://github.com/Pungyeon/clean-go-article
GitHub
GitHub - Pungyeon/clean-go-article: A reference for the Go community that covers the fundamentals of writing clean code and discusses…
A reference for the Go community that covers the fundamentals of writing clean code and discusses concrete refactoring examples specific to Go. - Pungyeon/clean-go-article
COME ON SHOW US THE REGULAR EXPRESSION
или как Cloudflare обещает показать регулярное выражение ...
https://blog.cloudflare.com/cloudflare-outage/
или как Cloudflare обещает показать регулярное выражение ...
https://blog.cloudflare.com/cloudflare-outage/
Брайн Керниган рассказывает как придумали название "grep" ->
eсли кратко то:
g/re/p
если догадались почему именно так, либо можно посмотреть видос:
https://www.youtube.com/watch?v=NTfOnGZUZDk
eсли кратко то:
g/re/p
если догадались почему именно так, либо можно посмотреть видос:
https://www.youtube.com/watch?v=NTfOnGZUZDk
YouTube
Where GREP Came From - Computerphile
Commonly used grep was written overnight, but why and how did it get its name? Professor Brian Kernighan explains.
EXTRA BITS: https://youtu.be/bSaBe6WiC2s
Inside an ALT Coin Mining Operation: COMING SOON
Unix Pipeline: https://youtu.be/bKzonnwoR2I
…
EXTRA BITS: https://youtu.be/bSaBe6WiC2s
Inside an ALT Coin Mining Operation: COMING SOON
Unix Pipeline: https://youtu.be/bKzonnwoR2I
…
Note #4 Дебажим приложение на Go в докере 🐳
Итак нам понадобится:
- прямые руки и тазик с предустановленным докером
$ cat Dockerfile
$ docker build -t my-golang-app .
# Это всего лишь один из вариантов, иногда нужно вместо bash сразу dlv запускать и так далее
$ docker run -it --rm my-golang-app bash
$ root@03c1977b1063:/go/src/app# dlv main.go
Error: unknown command "main.go" for "dlv"
Run 'dlv --help' for usage.
root@03c1977b1063:/go/src/app# dlv debug main.go
could not launch process: fork/exec /go/src/app/__debug_bin: operation not permitted
OOps...
Итак добавим параметры:
$ docker run -it --rm --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE my-golang-app bash
И вуаля 🎉
$ root@7dc3a7e8b3fc:/go/src/app# dlv debug main.go
Type 'help' for list of commands.
(dlv)
P.S. опять же этот же трюк можно использовать с docker-compose/ либо с multi-stage билдами. Если интересно как дебажить multi-stage билды на Го просьба поставить “+” в комментариях или кинуть помидором 🍅.
Итак нам понадобится:
- прямые руки и тазик с предустановленным докером
$ cat Dockerfile
FROM golang:1.13
WORKDIR /go/src/app
COPY . .
RUN go get -u github.com/go-delve/delve/cmd/dlv
CMD ["app"]
$ docker build -t my-golang-app .
# Это всего лишь один из вариантов, иногда нужно вместо bash сразу dlv запускать и так далее
$ docker run -it --rm my-golang-app bash
$ root@03c1977b1063:/go/src/app# dlv main.go
Error: unknown command "main.go" for "dlv"
Run 'dlv --help' for usage.
root@03c1977b1063:/go/src/app# dlv debug main.go
could not launch process: fork/exec /go/src/app/__debug_bin: operation not permitted
OOps...
Итак добавим параметры:
$ docker run -it --rm --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE my-golang-app bash
И вуаля 🎉
$ root@7dc3a7e8b3fc:/go/src/app# dlv debug main.go
Type 'help' for list of commands.
(dlv)
P.S. опять же этот же трюк можно использовать с docker-compose/ либо с multi-stage билдами. Если интересно как дебажить multi-stage билды на Го просьба поставить “+” в комментариях или кинуть помидором 🍅.
Note #5 Дебажим приложения в multi-stage докере 🐳
Давайте представим, что на проде у вас есть микросервис, каждый из которых живет в своем Dockerfile и естественно, как у всех взрослых дядь - это multi-stage Dockerfile. Более подробно о multi-stage можно прочитать в доках ( https://docs.docker.com/develop/develop-images/multistage-build/), если лень - то этопросто Dockerfile у которого есть 2 FROM ключевых слова и в мы что-то копируем из одного в другой слой.
Итак приступим 🐎:
Каждый день нам нужно разрабатывать и дебажить это приложение: внимательный читатель может предложить установить дебаггер внутри одного из слоев. Итак добавим что-то вроде:
И затем запустим что-то вроде этого:
И вот незадача, та же история будет если у вас
Есть замечательный флаг --target у docker build!
А как пофиксить это ☝️, читай мой прошлый пост https://yangx.top/golang_for_two/20 )
И Вуаля! Огромный Плюс ⚡️ данного подхода лично для меня, отсутствие Dockerfile-dev и вариантов.
P.S. Если же у тебя docker-compose, то в своем docker-compose.override.yml можно написать так:
🎉💥🎉
Давайте представим, что на проде у вас есть микросервис, каждый из которых живет в своем Dockerfile и естественно, как у всех взрослых дядь - это multi-stage Dockerfile. Более подробно о multi-stage можно прочитать в доках ( https://docs.docker.com/develop/develop-images/multistage-build/), если лень - то этопросто Dockerfile у которого есть 2 FROM ключевых слова и в мы что-то копируем из одного в другой слой.
Итак приступим 🐎:
docker build -t goapp:latest .
Sending build context to Docker daemon 22.53kB
Step 1/7 : FROM golang AS builder
...
Successfully tagged goapp:latest
Каждый день нам нужно разрабатывать и дебажить это приложение: внимательный читатель может предложить установить дебаггер внутри одного из слоев. Итак добавим что-то вроде:
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,5 @@
FROM golang AS builder
+RUN go get -u github.com/go-delve/delve/cmd/dlv
ADD . /src
RUN cd /src && go build -o goapp
И затем запустим что-то вроде этого:
➜ debug-multi-stage-docker-and-go docker run -it --entrypoint=dlv goapp
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"dlv\": executable file not found in $PATH": unknown.
И вот незадача, та же история будет если у вас
docker-compose
для локальной разработки или что-то еще. Как быть)Есть замечательный флаг --target у docker build!
docker build --target builder -t goapp:latest .
docker run -it goapp sh
# dlv debug main.go
could not launch process: fork/exec /src/__debug_bin: operation not permitted
А как пофиксить это ☝️, читай мой прошлый пост https://yangx.top/golang_for_two/20 )
И Вуаля! Огромный Плюс ⚡️ данного подхода лично для меня, отсутствие Dockerfile-dev и вариантов.
P.S. Если же у тебя docker-compose, то в своем docker-compose.override.yml можно написать так:
version: "3.4"
services:
app:
image: goapp:dev
build:
context: .
dockerfile: Dockerfile
target: builder
🎉💥🎉
Note #6 Дебажим тесты 🐛🔥
Итак, часто нужно запустить 1 тест да еще и в режиме отладки, например, когда вы написали тест который повторяет баг. Все очень просто (хотя из доков не особо очевидно):
dlv test -- -test.run NameOfYourTest/PartOfTheName* (по сути тоже самое что и go test -run)
Или живой пример:
Итак, часто нужно запустить 1 тест да еще и в режиме отладки, например, когда вы написали тест который повторяет баг. Все очень просто (хотя из доков не особо очевидно):
dlv test -- -test.run NameOfYourTest/PartOfTheName* (по сути тоже самое что и go test -run)
Или живой пример:
➜ debug_test dlv test -- -test.run TestFibonacciBigТакже можно запустить с -v (помним о go test -v):
(dlv) b main_test.go:6
Breakpoint 1 set at 0x115887f for github.com/andriisoldatenko/debug_test.TestFibonacciBig() ./main_test.go:6
(dlv) c
> github.com/andriisoldatenko/debug_test.TestFibonacciBig() ./main_test.go:6 (hits goroutine(17):1 total:1) (PC: 0x115887f)
1: package main
2:
3: import "testing"
4:
5: func TestFibonacciBig(t *testing.T) {
=> 6: var want int64 = 55
7: got := FibonacciBig(10)
8: if got.Int64() != want {
9: t.Errorf("Invalid Fibonacci value for N: %d, got: %d, want: %d", 10, got.Int64(), want)
10: }
11: }
(dlv)
➜ debug_test dlv test -- -test.v -test.run TestFibonacciBig
(dlv) c
=== RUN TestFibonacciBig
--- PASS: TestFibonacciBig (0.00s)
PASS
Designing Go code with interface chaining vs requiring deps.
https://gist.github.com/joncalhoun/0cd99c9082d2ba210c5169082038a420
Note: этот gist от создателя https://gophercises.com/, он написал в твиттере: времени нет писать 2 статьи - ловите код :)
https://gist.github.com/joncalhoun/0cd99c9082d2ba210c5169082038a420
Note: этот gist от создателя https://gophercises.com/, он написал в твиттере: времени нет писать 2 статьи - ловите код :)
Gist
chain_vs_not.go
GitHub Gist: instantly share code, notes, and snippets.
В одном из недавних постов я писал, что люди требуют крови!: https://yangx.top/golang_for_two/16
CloudFlare написал long read на эту тему, что пошло не так -> https://new.blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019
Но самое интересно, там есть Gif в которой тестируют RegExp и Go комюнити в лице Nate Fintch прикинул, что можно написать так:
// Equivalent normal code is worst case len(s)+1 steps:
CloudFlare написал long read на эту тему, что пошло не так -> https://new.blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019
Но самое интересно, там есть Gif в которой тестируют RegExp и Go комюнити в лице Nate Fintch прикинул, что можно написать так:
// Equivalent normal code is worst case len(s)+1 steps:
if !strings.HasSuffix(s, ";") {
return false
}
if !strings.Contains(s, "=") {
return false
}
Telegram
Go на двоих
COME ON SHOW US THE REGULAR EXPRESSION
или как Cloudflare обещает показать регулярное выражение ...
https://blog.cloudflare.com/cloudflare-outage/
или как Cloudflare обещает показать регулярное выражение ...
https://blog.cloudflare.com/cloudflare-outage/
В Go есть репозиторий "golang/proposal" который описывает процесс внесение изменений в язык. Так вот, Russ и ко. смекнули, (вероятно) после недавних зафейлиных предложений, что нужно что-то менять.
Мысли Russ'а можно прочитать тут, обещает опубликовать продолжение через пару дней🍿
Мысли Russ'а можно прочитать тут, обещает опубликовать продолжение через пару дней🍿
💡Рубрика интересный факт:
Кто из вас слышал, что в Go до версии 1.0 был debugger под названием, барабанная дробь: OGLE.
Те задумка была такая:
Кто из вас слышал, что в Go до версии 1.0 был debugger под названием, барабанная дробь: OGLE.
Те задумка была такая:
> go ogle main.goК сожалению, дебаггер не был готов к релизу go1.0 и его дропнули💩
Note #7 О стилистике Decode//UnMarshal 🐣
Недавно в твиттере возник вопрос, что лучше писать:
Если такого типа нет, оба варианта подойдут и как все знают на вкус и цвет фломастеры разные, хотя второй вариант более универсальный кмк.
Пару ссылок:
- Интересный gist о том как можно приводить типы между источниками
- Дока о том, что Decode - это обычно выражает Unmarshal BinaryUnmarshaler
Недавно в твиттере возник вопрос, что лучше писать:
// Option AИли так:
var v T
v.Decode(someData)
Option BНа самом деле все зависит от контекста, а именно вариант В) или использование метода вместо функции - позволяет типам удовлетворять интерфейсам, т.е другими словами, если у вас есть где-то
func (t *T) Decode(data []byte) {
// decode data into *t
}
type Decoder interface{ Decode([]byte) error }
,Если такого типа нет, оба варианта подойдут и как все знают на вкус и цвет фломастеры разные, хотя второй вариант более универсальный кмк.
Пару ссылок:
- Интересный gist о том как можно приводить типы между источниками
- Дока о том, что Decode - это обычно выражает Unmarshal BinaryUnmarshaler
Note #8 Ast T-shirt👕
Допустим вы решили себе напечатать футболку с куском кода который на Go, но hello-world это скучно. Вот вам идея, взять кусок синтаксического дерева из if err != nil. А если серьезно, то всегда интересно посмотреть - во что превратится ваша программа, когда компилятор ее парсит и строит ситаксическое дерево.
В общем получится что-то типа такого:
Если чуток почистить, то можно и на чашку вместить:
Ссылки:
- поиграться
- почитать
Допустим вы решили себе напечатать футболку с куском кода который на Go, но hello-world это скучно. Вот вам идея, взять кусок синтаксического дерева из if err != nil. А если серьезно, то всегда интересно посмотреть - во что превратится ваша программа, когда компилятор ее парсит и строит ситаксическое дерево.
В общем получится что-то типа такого:
55 . 1: *ast.IfStmt {
56 . . If: 5:2
57 . . Cond: *ast.BinaryExpr {
58 . . . X: *ast.Ident {
59 . . . . NamePos: 5:5
60 . . . . Name: "err"
61 . . . . Obj: *(obj @ 38)
62 . . . }
63 . . . OpPos: 5:9
64 . . . Op: !=
65 . . . Y: *ast.Ident {
66 . . . . NamePos: 5:12
67 . . . . Name: "nil"
68 . . . }
69 . . }
Если чуток почистить, то можно и на чашку вместить:
&ast.IfStmt{
Cond: &ast.BinaryExpr{
X: &ast.Ident{Name: "err"},
Op: token.NEQ,
Y: &ast.Ident{Name: "nil"},
},
}
Ссылки:
- поиграться
- почитать
pkg.go.dev
ast package - go/ast - Go Packages
Package ast declares the types used to represent syntax trees for Go packages.