Sunday, January 31, 2016

GoLang Misc



https://sourabhbajaj.com/mac-setup/Go/README.html
$ brew update
$ brew install golang
export GOPATH=$HOME/go-workspace # don't forget to change your path correctly!
export GOROOT=/usr/local/opt/go/libexec
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$GOROOT/bin^

https://medium.freecodecamp.org/writing-command-line-applications-in-go-2bc8c0ace79d

https://michaelheap.com/golang-how-to-go-get-private-repos/
Fortunately, as go get uses git, you can change your .gitconfig to force it to use SSH.
$ git config --global url."git@github.com:".insteadOf "https://github.com/"
$ cat ~/.gitconfig
[url "git@github.com:"]
    insteadOf = https://github.com/
Here, we say use git@github.com any time you’d use https://github.com. This works for everything, not just go get. It just has the nice side effect of using your SSH key any time you run go get too.
go env
https://stackoverflow.com/questions/12514037/golang-installing-packages-in-a-local-directory
You might want to consider using Go Version Manager (gvm).
Apart from switching between Go versions easily, it also lets you switch between pkgsets("workspaces").
First you create a set
gvm pkgset create myproject
and then you use it
gvm pkgset use myproject
Works like a charm.
https://groups.google.com/forum/#!topic/golang-nuts/WJJuQJOM-nQ
export GOPATH=$HOME/src/golang/go3p 
vi ~/.bash_profile
export PATH=$PATH:/usr/local/go/bin
go get -u 
https://marketplace.visualstudio.com/items?itemName=lukehoban.Go
First, you will need to install Visual Studio Code 0.10. In the command palette (cmd-shift-p) select Install Extension and choose Go.

In a terminal window with the GOPATH environment variable set to the GOPATH you want to work on, launch code. Open your GOPATH folder or any subfolder you want to work on, then open a .go file to start editing. You should seeAnalysis Tools Missing in the bottom right, clicking this will offer to install all of the Go tooling needed for the extension to support its full feature set. See the Tools section below for more details.
Note: Users may want to consider turning Auto Save on in Visual Studio Code ("files.autoSave": "afterDelay") when using this extension. Many of the Go tools work only on saved files, and error reporting will be more interactive with Auto Save turned on. If you do turn Auto Save on, you may also want to turn format-on-save off ("go.formatOnSave": "false"), so that it is not triggered while typing.

To use the debugger, you must currently manually install delve. See the Installation Instructions for full details. On OS X it requires creating a self-signed cert to sign the dlv binary.
go get -u github.com/newhook/go-symbols

To run go program: go run test.go

http://www.tutorialspoint.com/go/go_basic_syntax.htm
package main

import "fmt"

func main() {
   fmt.Println("Hello, World!")
}
http://marcio.io/2015/07/supercharging-atom-editor-for-go-development/

go version
debug
https://github.com/mailgun/godebug
go get github.com/mailgun/godebug
https://atom.io/packages/go-debug
A go debugger for atom using delve.
GoEclipse

https://blog.cloudflare.com/go-has-a-debugger-and-its-awesome/

https://github.com/derekparker/delve/blob/master/Documentation/installation/osx/install.md
brew install go-delve/delve/delve
xcode-select --install
DevToolsSecurity -enable

Visual Code Studio
            "env": {
                "NODE_ENV": "development"
            },

    "args": [
        "hello!"
    ]
go run helloworld.go go build helloworld.go ./helloworld go get gopl.io/ch1/helloworld func, var, const, and type os.Args[0], is the name of the command itself for i := 1; i < len(os.Args); i++ { s += sep + os.Args[i] sep = " " } The := symbol is part of a short variable declaration, a statement that declares one or more variables and gives them appropriate types based on the initializer values. for initialization; condition; post { // zero or more statements } Go does not permit unused local variables for _, arg := range os.Args[1:] { s += sep + arg sep = " " } s := "" it may be used only within a function, not for package-level variables. var s string var s = "" var s string = "" A simpler and more efficient solution would be to use the Join function from the strings package: fmt.Println(strings.Join(os.Args[1:], " ")) counts := make(map[string]int) input := bufio.NewScanner(os.Stdin) for input.Scan() { counts[input.Text()]++ } // NOTE: ignoring potential errors from input.Err() for line, n := range counts { if n > 1 { fmt.Printf("%d\t%s\n", n, line) } } for _, arg := range files { f, err := os.Open(arg) if err != nil { fmt.Fprintf(os.Stderr, "dup2: %v\n", err) continue } countLines(f, counts) f.Close() } func countLines(f *os.File, counts map[string]int) { input := bufio.NewScanner(f) for input.Scan() { counts[input.Text()]++ } // NOTE: ignoring potential errors from input.Err() } "io/ioutil" "math" "math/rand" var palette = []color.Color{color.White, color.Black} anim := gif.GIF{LoopCount: nframes} "net/http" resp, err := http.Get(url) b, err := ioutil.ReadAll(resp.Body) resp.Body.Close() "time" start := time.Now() ch := make(chan string) for _, url := range os.Args[1:] { go fetch(url, ch) // start a goroutine } for range os.Args[1:] { fmt.Println(<-ch) // receive from channel ch } fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds()) func fetch(url string, ch chan<- string) { start := time.Now() resp, err := http.Get(url) if err != nil { ch <- fmt.Sprint(err) // send to channel ch return } nbytes, err := io.Copy(ioutil.Discard, resp.Body) resp.Body.Close() // don't leak resources if err != nil { ch <- fmt.Sprintf("while reading %s: %v", url, err) return } secs := time.Since(start).Seconds() ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url) } A goroutine is a concurrent function execution. A channel is a communication mechanism that allows one goroutine to pass values of a specified type to another goroutine. The io.Copy function reads the body of the response and discards it by writing to the ioutil.Discard output stream. When one goroutine attempts a send or receive on a channel, it blocks until another goroutine attempts the corresponding receive or send operation, at which point the value is transferred and both goroutines proceed. In this example, each fetch sends a value (ch <- expression) on the channel ch, and main receives all of them (<-ch). "log" "net/http" http.HandleFunc("/", handler) // each request calls handler log.Fatal(http.ListenAndServe("localhost:8000", nil)) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path) } "sync" var mu sync.Mutex http.HandleFunc("/count", counter) mu.Lock() fmt.Fprintf(w, "Count %d\n", count) mu.Unlock() if err := r.ParseForm(); err != nil { log.Print(err) } Named types type Point struct { X, Y int } var p Point Pointers are explicitly visible. The & operator yields the address of a variable, and the * operator retrieves the variable that the pointer refers to, but there is no pointer arithmetic. https://golang.org/pkg https://godoc.org go doc http.ListenAndServe var name type = expression var b, f, s = true, 2.3, "four" // bool, float64, string i, j = j, i // swap values of i and j := is a declaration, whereas = is an assignment A short variable declaration must declare at least one new variable p := &x // p, of type *int, points to x *p = 2 // equivalent to x = 2 "flag" var n = flag.Bool("n", false, "omit trailing newline") var sep = flag.String("s", " ", "separator") fmt.Print(strings.Join(flag.Args(), *sep)) if !*n { fmt.Println() } The variables sep and n are pointers to the flag variables, which must be accessed indirectly as *sep and *n. When the program is run, it must call flag.Parse before the flags are used, to update the flag variables from their default values. The non-flag arguments are available from flag.Args() as a slice of strings. If flag.Parse encounters an error, it prints a usage message and calls os.Exit(2) to terminate the program. p := new(int) // p, of type *int, points to an unnamed int variable fmt.Println(*p) // "0" TUPLE ASSIGNMENT All of the right-hand side expressions are evaluated before any of the variables are updated. medals := []string{"gold", "silver", "bronze"} A type declaration defines a new named type that has the same underlying type as an existing type. The named type provides a way to separate different and perhaps incompatible uses of the underlying type so that they can’t be mixed unintentionally. type Celsius float64 func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) } exported identifiers start with an upper-case letter. Only one file in each package should have a package doc comment. Extensive doc comments are often placed in a file of their own, conventionally called doc.go. By default, the short name is the package name—tempconv in this case—but an import declaration may specify an alternative name to avoid a conflict. It is an error to import a package and then not refer to it. Better still, use the golang.org/x/tools/cmd/goimports tool, which automatically inserts and removes packages from the import declaration as necessary; Such init functions can’t be called or referenced, but otherwise they are normal functions. basic types, aggregate types, reference types, and interface types int8, int16, int32, and int64, and corresponding unsigned versions uint8, uint16, uint32, and uint64. byte, float64 should be preferred for most purposes because float32 computations accumulate error rapidly

var a [3]int             // array of 3 integers
fmt.Println(a[len(a)-1]) // print the last element, a[2]
var q [3]int = [3]int{1, 2, 3}
q := [...]int{1, 2, 3}
The size of an array is part of its type, so [3]int and [4]int are different types.

r := [...]int{99: -1}
symbol := [...]string{USD: "$", EUR: "€", GBP: "£", RMB: "¥"}
When a function is called, a copy of each argument value is assigned to the corresponding parameter variable, so the function receives a copy, not the original.
func zero(ptr *[32]byte) {
    for i := range ptr {
        ptr[i] = 0
    }
}
Slices represent variable-length sequences whose elements all have the same type. A slice has three components: a pointer, a length, and a capacity.
months := [...]string{1: "January", /* ... */, 12: "December"}

Since a slice contains a pointer to an element of an array, passing a slice to a function permits the function to modify the underlying array elements.
func reverse(s []int) {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }
}
a := [...]int{0, 1, 2, 3, 4, 5}
reverse(a[:])
Unlike arrays, slices are not comparable, so we cannot use == to test whether two slices contain the same elements
runes = append(runes, r)

top := stack[len(stack)-1] // top of stack
stack = stack[:len(stack)-1] // pop
func remove(slice []int, i int) []int {
    copy(slice[i:], slice[i+1:])
    return slice[:len(slice)-1]
}
ages := map[string]int{
    "alice":   31,
    "charlie": 34,
}
sort.Strings(names)
names := make([]string, 0, len(ages))
age, ok := ages["bob"]
if !ok { /* "bob" is not a key in this map; age == 0. */ }
if age, ok := ages["bob"]; !ok { /* ... */ }

func equal(x, y map[string]int) bool {
    if len(x) != len(y) {
        return false
    }
    for k, xv := range x {
        if yv, ok := y[k]; !ok || yv != xv {
            return false
        }
    }
    return true
}
var graph = make(map[string]map[string]bool)

func addEdge(from, to string) {
    edges := graph[from]
    if edges == nil {
        edges = make(map[string]bool)
        graph[from] = edges
    }
    edges[to] = true
}

func hasEdge(from, to string) bool {
    return graph[from][to]
}
The name of a struct field is exported if it begins with a capital letter;
type tree struct {
    value       int
    left, right *tree
}

// Sort sorts values in place.
func Sort(values []int) {
    var root *tree
    for _, v := range values {
        root = add(root, v)
    }
    appendValues(values[:0], root)
}

// appendValues appends the elements of t to values in order
// and returns the resulting slice.
func appendValues(values []int, t *tree) []int {
    if t != nil {
        values = appendValues(values, t.left)
        values = append(values, t.value)
        values = appendValues(values, t.right)
    }
    return values
}

func add(t *tree, value int) *tree {
    if t == nil {
        // Equivalent to return &tree{value: value}.
        t = new(tree)
        t.value = value
        return t
    }
    if value < t.value {
        t.left = add(t.left, value)
    } else {
        t.right = add(t.right, value)
    }
    return t
}
p := Point{1, 2}
anim := gif.GIF{LoopCount: nframes}
type Circle struct {
    Point
    Radius int
}
w = Wheel{Circle{Point{8, 8}, 5}, 20}
the outer struct type gains not just the fields of the embedded type but its methods too.

Year   int  `json:"released"`
Color  bool `json:"color,omitempty"`
data, err := json.Marshal(movies)
data, err := json.MarshalIndent(movies, "", "    ")
var titles []struct{ Title string }
if err := json.Unmarshal(data, &titles); err != nil {}
"encoding/json"
q := url.QueryEscape(strings.Join(terms, " "))
resp, err := http.Get(IssuesURL + "?q=" + q)
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
    resp.Body.Close()
    return nil, err
}
resp.Body.Close()
Title:  {{.Title | printf "%.64s"}}
Age:    {{.CreatedAt | daysAgo}} days
report, err := template.New("report").
    Funcs(template.FuncMap{"daysAgo": daysAgo}).
    Parse(templ)
var report = template.Must(template.New("issuelist").
    Funcs(template.FuncMap{"daysAgo": daysAgo}).
    Parse(templ))
var data struct {
    A string        // untrusted plain text
    B template.HTML // trusted HTML
}
func first(x int, _ int) int { return x }

deadline := time.Now().Add(timeout)
for tries := 0; time.Now().Before(deadline); tries++ {
    _, err := http.Head(url)
    if err == nil {
        return nil // success
    }
    log.Printf("server not responding (%s); retrying...", err)
    time.Sleep(time.Second << uint(tries)) // exponential back-off
}
The zero value of a function type is nil. Calling a nil function value causes a panic:

func squares() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}
function values are not just code but can have state. The anonymous inner function can access and update the local variables of the enclosing function.
var prereqs = map[string][]string{ }
func topoSort(m map[string][]string) []string {
    var order []string
    seen := make(map[string]bool)
    var visitAll func(items []string)

    visitAll = func(items []string) {
        for _, item := range items {
            if !seen[item] {
                seen[item] = true
                visitAll(m[item])
                order = append(order, item)
            }
        }
    }

    var keys []string
    for key := range m {
        keys = append(keys, key)
    }

    sort.Strings(keys)
    visitAll(keys)
    return order
}
var rmdirs []func()
for _, d := range tempDirs() {
    dir := d               // NOTE: necessary!
    os.MkdirAll(dir, 0755) // creates parent directories too
    rmdirs = append(rmdirs, func() {
        os.RemoveAll(dir)
    })
}

// ...do some work...

for _, rmdir := range rmdirs {
    rmdir() // clean up
}
the actual call is deferred until the function that contains the defer statement has finished.

func bigSlowOperation() {
    defer trace("bigSlowOperation")() // don't forget the extra parentheses
    // ...lots of work...
    time.Sleep(10 * time.Second) // simulate slow operation by sleeping
}

func trace(msg string) func() {
    start := time.Now()
    log.Printf("enter %s", msg)
    return func() { log.Printf("exit %s (%s)", msg, time.Since(start)) }
}
var httpSchemeRE = regexp.MustCompile(`^https?:`) // "http:" or "https:"
func printStack() {
    var buf [4096]byte
    n := runtime.Stack(buf[:], false)
    os.Stdout.Write(buf[:n])
}
func Parse(input string) (s *Syntax, err error) {
    defer func() {
        if p := recover(); p != nil {
            err = fmt.Errorf("internal error: %v", p)
        }
    }()
    // ...parser...
}
A method is declared with a variant of the ordinary function declaration in which an extra parameter appears before the function name. The parameter attaches the function to the type of that parameter.

func (p Point) Distance(q Point) float64 {
    return math.Hypot(q.X-p.X, q.Y-p.Y)
}
convention dictates that if any method of Point has a pointer receiver, then all methods of Point should have a pointer receiver, even ones that don’t strictly need it.

Learning Go Web Development
always run go fmt before shipping or pushing your code.
go get command reads the master branch of the remote repository.
fmt.Println will produce desired content at the console level, Fprintln allows you to direct output to any writer.
http.ListenAndServe(PORT, http.FileServer(http.Dir("/var/www")))
gorilla/mux: This is intended to create flexible routes that allow regular expressions to dictate available variables for routers.

"github.com/gorilla/mux"
"net/http"
func pageHandler(w http.ResponseWriter, r *http.Request) {
  vars := mux.Vars(r)
  pageID := vars["id"]
  fileName := "files/" + pageID + ".html"
  http.ServeFile(w,r,fileName)
}
rtr := mux.NewRouter()
rtr.HandleFunc("/pages/{id:[0-9]+}",pageHandler)
http.Handle("/",rtr)
err := os.Stat(fileName)
  if err != nil {
    fileName = "files/404.html"
  }

http.ServeFile(w,r,fileName)
"database/sql"
_ "github.com/go-sql-driver/mysql"

It's also often used when a developer plans to use a library, but hasn't yet. By prepending the package this way, it allows the import declaration to stay without causing a compiler error.

var database *sql.DB
type Page struct {
  Title   string
  Content string
  Date    string
}
dbConn := fmt.Sprintf("%s:%s@tcp(%s)/%s", DBUser, DBPass, DBHost, DBDbase)
db, err := sql.Open("mysql", dbConn)
thisPage := Page{}
err := database.QueryRow("SELECT page_title,page_content,page_date FROM pages WHERE id=?", pageID).Scan(&thisPage.Title, &thisPage.Content, &thisPage.Date)
routes.HandleFunc("/page/{guid:[0-9a-zA\\-]+}", ServePage)
http.Error(w, http.StatusText(404), http.StatusNotFound)
tpl, err := template.New("mine").Parse(`<h1>{{.Title}}</h1>`)
t, _ := template.ParseFiles("templates/blog.html")
t.Execute(w, thisPage)

RawContent string
Content    template.HTML
err := database.QueryRow("SELECT page_title,page_content,page_date FROM pages WHERE page_guid=?", pageGUID).Scan(&thisPage.Title, &thisPage.RawContent, &thisPage.Date)
thisPage.Content = template.HTML(thisPage.RawContent)
http.Redirect(w, r, "/home", 301)

var Pages = []Page{}
defer pages.Close()
for pages.Next() {
  thisPage := Page{}
  pages.Scan(&thisPage.Title, &thisPage.RawContent, &thisPage.Date)
  thisPage.Content = template.HTML(thisPage.RawContent)
  Pages = append(Pages, thisPage)
}
t, _ := template.ParseFiles("templates/index.html")
t.Execute(w, Pages)

{{range .}}
  <div><a href="!">{{.Title}}</a></div>
  <div>{{.Content}}</div>
  <div>{{.Date}}</div>
{{end}}
we can essentially share a method between the application and the template.
routes.HandleFunc("/api/pages/{guid:[0-9a-zA\\-]+}", APIPage).
  Methods("GET").
  Schemes("https")
APIOutput, err := json.Marshal(thisPage)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, thisPage)
a good policy is to keep the most recent URL canonical and deprecate to explicit version URLs.

certificates, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
tlsConf := tls.Config{Certificates: []tls.Certificate{certificates}}
tls.Listen("tcp", PORT, &tlsConf)

type JSONResponse struct {
  Fields map[string]string
}

err := r.ParseForm()
name := r.FormValue("name")
res, err := database.Exec("INSERT INTO comments SET comment_name=?, comment_email=?, comment_text=?", name, email, comments)
id, err := res.LastInsertId()
var resp JSONResponse
resp.Fields["id"] = string(id)
resp.Fields["added"] =  commentAddedBool
jsonResp, _ := json.Marshal(resp)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, jsonResp)

routes.HandleFunc("/api/comments/{id:[\\w\\d\\-]+}", APICommentPut).
  Methods("PUT")

http://blog.panic.so/share/2015/09/17/Golang%E5%A6%82%E4%BD%95%E5%B9%B6%E5%8F%91/

Threads, Processes and Green Threads

在linux中,进程和线程的都由task_struct对象来表示,区别在于signal handler,以及线程共享了虚拟内存空间等,尽管这些区别可能会让线程在创建和context switch的时候更加轻松些,但其实看起来没有明显的区别。
当然进程并不只是task_struct对象,它是可执行代码和所操作数据的集合,是一个动态的实体,随着可执行代码的执行而动态变化。进程同时包含了程序计数器,CPU内的各个寄存器以及存放临时变量的程序栈等。所以我们大概可以想象出进程在进行context switch时要进行的操作。
kernel负责对进程(线程)进行调度,系统会把不同的进程运行在不同的CPU上来提升CPU的利用率。当一个进程阻塞时,CPU会被调度执行其他的进程。调度的目的是提高系统的在单位时间内执行的任务吞吐量,降低任务从可执行到执行结束的时间,使进程占用的资源更加合理,系统对于进程和线程的调度是无差别的。
green threads可以理解是用户态线程,它运行在用户空间中。也就是我们在程序层面实现了类似操作系统线程这样的概念,通常这个实现逻辑会简单许多。
green threads可以带来什么?最显而易见的是:在不支持线程的操作系统上,我们依旧可以在语言层面上实现green threads。其次操作系统提供的线程是一个大而全的对象,而对于用户程序来说,诸多功能是冗余的,因此green threads的构造可以更简单,调度策略也更加简单。goroutine可以理解为是一种green threads,它建立在系统线程之上,所以go程序可以并行执行成千上万个goroutine。

Goroutine

green threads的实现通常有三种模型:多个green threads运行在同一个kernel thread上,优点是context switch的速度快,但是只能运行在一个核上;一个green thread对应一个kernel thread,优点是可以利用多核,但是由于绑定关系context swtich会更耗时。
goroutine使用了第三种模型,也就是多个green threads运行在多个kernel threads上,既可以快速的进行context switch又可以很好的利用多核。显然缺点是调度策略会因此变得非常复杂。goroutine的实现使用work stealing算法,定义了MPG三个角色,分别代表kernel threads,processor和goroutine。
image
P也可以理解为context,我们设置的GOMAXPROCS就是指的P的数量。P负责完成对G和M的调度。P维护了一个deque来存放可执行的G,进行调度时切换当前执行的G,从deque顶部取出下一个G继续执行。当G进行syscall阻塞时,不仅需要切换G,M也需要进行切换来保证P能够继续执行后面的G,当阻塞的G-M对就绪时会被重新调度执行。同时当P维护的所有的G执行结束后,会从别的P的deque的steal一半的G放入自己的deque中执行,这也就是为什么叫做work steal算法。

Non-Blocking I/O

Go提供了同步阻塞的IO模型,但Go底层并不没有使用kernel提供的同步阻塞I/O模型。green threads通常在实现的时候会避免使用同步阻塞的syscall,原因在于当kernel threads阻塞时,需要创建新的线程来保证green threads能够继续执行,代价非常高。所以Go在底层使用非阻塞I/O的模型来避免M阻塞。
当goroutine尝试进行I/O操作而IO未就绪时,syscall返回error,当前执行的G设置为阻塞,而M可以被调度继续执行其他的G,这样就不需要再去创建新的M。当然只是Non-Blocking I/O还不够,Go实现了netpoller来进行I/O的多路复用,在linux下通过epoll实现,epoll提供了同步阻塞的多路复用I/O模型。当G阻塞到I/O时,将fd注册到epoll实例中进行epoll_wait,就绪的fd回调通知给阻塞的G,G重新设置为就绪状态等待调度继续执行,这种实现使得Go在进行高并发的网络通信时变得非常强大,相比于php-fpm的多进程模型,Go Http Server使用很少的线程运行非常多的goroutine,而尽可能的让每一个线程都忙碌起来,这样提高了CPU的利用率,减少了系统进行context switch的开销,从而hold住更大的并发量级。



Go 语言在工业上有非常多的应用,包括分布式系统和云计算平台等。而 Go 语言并行性能高、部署方便和简单便捷等特性令其在一些应用上超过了 Python


Go 编程无法成功扩展的一大原因在于错误检查和错误处理代码的编写。总体来看,Go 编程代码检查错误太多,但处理这些错误的代码却非常不足(下文将给出解释)。该设计草案旨在通过引入比当前惯用的「赋值和 if 语句」(assignment-and-if-statement)组合更轻量级的错误检查语法来解决这个问题。
Go 极其地快。其性能与 Java 或 C++相似。在我们的使用中,Go 一般比 Python 要快 30 倍
原因 2:语言性能很重要
Python 非常棒,但是其在序列化/去序列化、排序和聚合中表现欠佳。我们经常会遇到这样的问题:Cassandra 用时 1ms 检索了数据,Python 却需要 10ms 将其转化成对象。

其唯一的创新之处是 goroutines 和通道。Goroutines 是 Go 面向线程的轻量级方法,而通道是 goroutines 之间通信的优先方式。

创建 Goroutines 的成本很低,只需几千个字节的额外内存,正由于此,才使得同时运行数百个甚至数千个 goroutines 成为可能。你可以借助通道实现 goroutines 之间的通信。Go 运行时间可以表示所有的复杂性。Goroutines 以及基于通道的并发性方法使其非常容易使用所有可用的 CPU 内核,并处理并发的 IO——所有不带有复杂的开发。相较于 Python/Java,在一个 goroutine 上运行一个函数需要最小的样板代码。你只需使用关键词「go」添加函数调用:
原因 5:快速的编译时间

原因 8:GOFMT,强制代码格式

Gofmt 是一种强大的命令行功能,内建在 Go 的编译器中来规定代码的格式。从功能上看,它类似于 Python 的 autopep8。格式一致很重要,但实际的格式标准并不总是非常重要。Gofmt 用一种官方的形式规格代码,避免了不必要的讨论。

原因 9:gRPC 和 Protocol Buffers

Go 语言对 protocol buffers 和 gRPC 有一流的支持。这两个工具能一起友好地工作以构建需要通过 RPC 进行通信的微服务器(microservices)。我们只需要写一个清单(manifest)就能定义 RPC 调用发生的情况和参数,然后从该清单将自动生成服务器和客户端代码。这样产生代码不仅快速,同时网络占用也非常少。



Markdown Tips and Tricks



https://www.saplinglearning.com/ibiscms/help.php?file=advanced_markdown.html

Hyperlinked Images

The Enhancing Text With Markdown document gives instructions for creating web links and inserting images. It may not be obvious that these can be combined to create images that are also clickable links.
[the google search engine][google]
![the google logo][logo]
Above are a standard web link and image. By placing the image where the link text would be found you end up with this:
[![the google logo][logo]][google]
This line above, in combination with the following link definitions elsewhere in the document:
[logo]: http://www.google.com/images/logo.gif
[google]: http://www.google.com/ "click to visit Google.com"
combine to produce the following clickable image link (with tooltip if you hover over it):
the google logo



If you don’t want a URL to be automatically linked, you can remove the link by denoting the URL as code with tick marks.
`http://www.example.com`
https://www.eviltester.com/2018/07/freemind-scripting.html
write the slides in markdown
process the markdown in Marp to generate slides
process the markdown in Pandoc (via pandocifier) to create longer documentation

xmind - not free


Online markdown editors for note-taking
  • StackEdit – Recommended
  • HackMD – Basic for collaboration
Mac apps markdown editors for note-taking
  • Typora  – Recommended: Beautiful and intuitive 
  • Boostnote – Basic and working
Mac coding editor apps as Markdown editor for note-taking
  • Atom – Usable with markdown preview plus and mindmap packages
  • Visual Studio Code – Works with Markdown Preview Enhanced

  • Hexo – Install and run your blog framework with Markdown support. There is a learning curve involved here and it may be over the top for just a note-taking purpose
  • Jekyll – From text with markdown support to sites and blog on Github pages for free hosting.
More Markdown
https://www.evernote.com/shard/s461/client/snv?noteGuid=022be86e-1a3e-4836-b7ea-1f6055d1800b&noteKey=677ba48a7c1a754f47d9b5454ee71479&sn=https%3A%2F%2Fwww.evernote.com%2Fshard%2Fs461%2Fsh%2F022be86e-1a3e-4836-b7ea-1f6055d1800b%2F677ba48a7c1a754f47d9b5454ee71479&title=More%2BMarkdown

https://stackoverflow.com/questions/39422404/setting-bgcolor-in-markdown
<style type="text/css">
  body {
    background-color: #336655;
  }
</style>

<style type="text/css">

  .post-body {

    background-color: #336655;

    background-image: url("https://cdn.pixabay.com/photo/2016/07/10/11/55/cat-1507600_960_720.jpg");

    background-repeat: no-repeat;
  }
</style>


Embed Gists

https://stackoverflow.com/questions/24319505/how-can-one-display-images-side-by-side-in-a-github-readme-md/24320279#24320279
To your specific example it would look something like this:
Solarized dark             |  Solarized Ocean
:-------------------------:|:-------------------------:
![](https://...Dark.png)  |  ![](https://...Ocean.png)

https://www.chronicle.com/blogs/profhacker/markdown-the-syntax-you-probably-already-know/35295

https://brettterpstra.com/2015/08/24/write-better-markdown/
One overall problem in Markdown 1.0’s syntax is that it isn’t clear when you need blank lines to separate block-level constructs
https://www.markdownguide.org/extended-syntax/
You can align text in the columns to the left, right, or center by adding a colon (:) to the left, right, or on both side of the hyphens within the header row.
| Syntax      | Description | Test Text     |
| :---        |    :----:   |          ---: |
| Header      | Title       | Here's this   |
| Paragraph   | Text        | And more      |


To create a footnote reference, add a caret and an identifier inside brackets ([^1]). Identifiers can be numbers or words, but they can’t contain spaces or tabs. Identifiers only correlate the footnote reference with the footnote itself — in the output, footnotes are numbered sequentially.

Add the footnote using another caret and number inside brackets with a colon and text ([^1]: My footnote.). You don’t have to put footnotes at the end of the document. You can put them anywhere except inside other elements like lists, block quotes, and tables.

Don’t forget about spaces, either. A space after a list item delimiter (-*+, or 1.) is required by most processors, but a space after hashmarks in headlines usually isn’t. It looks better, though, and ensures universal compatibility.


As Gruber noted early on, nested lists are an exception to the never-too-much-whitespace rule. Blank lines between list items can be interpreted very differently between processors. Keep list items consecutive, but you can use blank lines above paragraphs within lists. Just follow the last paragraph immediately with another list item (or the end of the list).
* list item 1

    paragraph in list item 1
* list item 2
COPY
Empty lines in block quotes are handled differently between flavors as well. The most common way to make a multi-paragraph block quote is to use a greater than symbol on each blank line:

> paragraph one
>
> paragraph two
>> nested paragraph
>>


<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>R</kbd

https://www.k15t.com/blog/2015/04/markdown-vs-rich-formatting-who-will-win-the-ultimate-text-processing-competition

Round #6: Images and Other Media Assets

Markdown: “OK, I admit it – embedding images into a plain text document format isn’t easy.” There are two different ways to do it:
  • Inline (within a paragraph): ![alt text](/path/to/img.jpg "title"), for example !Logo (/folder/logo.jpg "My Logo")
  • Reference-style[id]: url/to/image "Optional title attribute", for example [logo]: /folder/logo.jpg "My Logo"
  • Either place the URL after the link text, e.g. [link text](http://example.com/ “Title”),
  • or include it as a reference, with the ID placed behind the link text.”
https://tech.agilitynerd.com/maximize-and-minimize-code-blocks-in-revealjs-slide-shows.html
I threw together a little JavaScript to add "+" and "-" buttons next to each code section that maximizes/restores the code blocks for easier viewing during the presentation:


Sometimes it's desirable to have an element, like an image or video, stretch to consume as much space as possible within a given slide. This can be done by adding the .stretch class to an element as seen below:
<section>
 <h2>This video will use up the remaining space on the slide</h2>
    <video class="stretch" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
</section>
https://en.support.wordpress.com/wordpress-editor/blocks/markdown-block/#writing-with-markdown
  1. In WP Admin, go to Jetpack → Settings → Writing.
  2. Under Composing click the button next to “Write posts or pages in plain-text Markdown syntax.”
https://en.support.wordpress.com/editors/#classic-editor
https://github.com/hakimel/reveal.js#full-setup
External Markdown

https://github.com/hakimel/reveal.js/issues/1227
for (var slide of document.getElementsByTagName('section')){
  if (!(slide.getAttribute('data-background') ||
        slide.getAttribute('data-background-video') ||
        slide.getAttribute('data-background-iframe'))){
    slide.setAttribute('data-background-iframe', 'background.html')
  }
}
https://www.raymondcamden.com/2012/07/23/Adding-a-background-image-to-a-revealjs-presentation
Set data-state="something" on a slide and "something" will be added as a class to the document element when the slide is open. This let's you apply broader style changes, like switching the background.
html.intro body {
background:url("images/raiders_warehouse.jpg");
background-position:center;
background-size: 100%;
}
https://bookdown.org/yihui/rmarkdown/ioslides-presentation.html#incremental-bullets

https://stackoverflow.com/questions/975264/how-do-i-set-an-html-class-attribute-in-markdown
https://www.npmjs.com/package/markdown-it-attrs
Add classes, identifiers and attributes to your markdown with {.class #identifier attr=value attr2="spaced value"} curly brackets, similar to pandoc's header attributes.
Headings can be assigned attributes using this syntax at the end of the line containing the heading text:
{#identifier .class .class key=value key=value}
Thus, for example, the following headings will all be assigned the identifier foo:
# My heading {#foo}

# header {.style-me}
paragraph {data-toggle=modal}

Output:

<h1 class="style-me">header</h1>
<p data-toggle="modal">paragraph</p>

Works with inline elements too:

paragraph *style me*{.red} more text
https://lornajane.net/posts/2016/switching-to-reveal-js-for-presentations
 // More info https://github.com/hakimel/reveal.js#configuration
 Reveal.initialize({
            history: true,
            progress: false,
            controls: false,
            center: false,
            slideNumber: true,
            transition: 'none',
            transitionSpeed: 'fast',
            width: 960,
            height: 540,
I found this StackOverflow question and added a footer using the linked example.

  • s to show the speaker notes in a new window, these show the current and next slides, the current time and the elapsed time - if you set up before you actually start talking, you can click on the time block to reset the timer. This also shows speaker notes but I don't use those.
  • arrow keys to move between slides
  • f to full-screen Chrome
  • b to black the screen
I'm also a Vimium user, which is a plugin that lets you use your web browser from the keyboard. I would like to find out how to detect reveal.js and disable vimium but for now I am just excluding the "f" and "b" keys in Vimium for the http://localhost:8000 that reveal.js usually runs on.
https://github.com/rajgoel/reveal.js-plugins

https://github.com/hakimel/reveal.js/wiki/Keyboard-Shortcuts
  • NSPACE: Next slide
  • P: Previous slide
  • H: Navigate left
  • L: Navigate right
  • K: Navigate up
  • J: Navigate down
  • Home: First slide
  • End: Last slide
  • B.: Pause (Blackout)
  • F: Fullscreen
  • ESCO: Slide overview / Escape from full-screen
  • S: Speaker notes view
  • ?: Show keyboard shortcuts
  • alt + click: Zoom in. Repeat to zoom back out.
https://github.com/hakimel/reveal.js/blob/master/js/reveal.js
https://medium.com/myplanet-musings/building-a-responsive-reveal-js-theme-399179632cc6
Reveal.initialize({
    width: "100%",
    height: "100%",
    margin: 0,
    minScale: 1,
    maxScale: 1
});

embedded: false,
https://github.com/hakimel/reveal.js#theming
https://stackoverflow.com/questions/30988306/level-1-and-level-2-slides-in-reveal-js-using-pandoc
The reveal.js framework allows a 2D setup: grouping of slides within slide subsets "vertically", and grouping of the slide subsets horizontally. In markdown, it can be achieved like this:
# Head1

## Below 1

text below 1

## Below 2

text below 2

# Head 2

https://pandoc.org/MANUAL.html#producing-slide-shows-with-pandoc
The document is carved up into slides according to the following rules:
  • A horizontal rule always starts a new slide.
  • A heading at the slide level always starts a new slide.
  • Headings below the slide level in the hierarchy create headings within a slide.
  • Headings above the slide level in the hierarchy create “title slides,” which just contain the section title and help to break the slide show into sections. Non-slide content under these headings will be included on the title slide (for HTML slide shows) or in a subsequent slide with the same title (for beamer).
  • A title page is constructed automatically from the document’s title block, if present. (In the case of beamer, this can be disabled by commenting out some lines in the default template.)

https://github.com/jgm/pandoc/wiki/Using-pandoc-to-produce-reveal.js-slides
pandoc -t revealjs -s -o myslides.html myslides.md -V revealjs-url=https://revealjs.com
https://stackoverflow.com/questions/22194261/embedding-entire-reveal-js-presentation-inside-a-div
You can't do that with a div. What you describe sounds exactly like what iframes are useful for.
<iframe width="400" height="400" marginheight="0" marginwidth="0" src="/your/reveal/slideshow.html">
  Fallback text here for unsupporting browsers, of which there are scant few.
</iframe>
markdown to google slide
https://github.com/gsuitedevs/md2googleslides
md2gslides slides.md

Slide
https://github.com/gnab/remark/wiki/Markdown
A line containing three dashes, represents a slide separator (not a horizontal rule, <hr />, like in regular Markdown). Thus, a simple Markdown text like the one below represents a slideshow with two slides:
# Slide 1
This is slide 1
---
# Slide 2
This is slide 2

Incremental Slides

To avoid having to duplicate content if a slide is going to add to the previous one, using only two dashes to separate slides will make a slide inherit the content of the previous one:
# Slide

- bullet 1
--

- bullet 2


A line containing three question marks, represents a separator of content and note of the slide:

# Slide

Some content.

???
Some note.
A notes open version of a slide show can be shared by sharing the url with #p1 appended. Such as remarkjs.com/#p1.

With the highlightLines configuration option enabled, lines prefixed with * will get highlighted with a yellow background, which can be handy for bringing attention to specific parts of code snippets, i.e.:
Implicit return statement:

```ruby
def add(a,b)
*  a + b
end

# Notice how there is no return statement.
  • Strikethrough: ~~your text~~
    • your text
  • Inline code: surround your text with backtick symbols `
    • you code
https://guides.github.com/features/mastering-markdown/

Inline code

I think you should use an
`<addr>` element here instead.

Task Lists

- [x] @mentions, #refs, [links](), **formatting**, and <del>tags</del> supported
- [x] list syntax required (any unordered or ordered list supported)
- [x] this is a complete item
- [ ] this is an incomplete item

Inline `code` has `back-ticks around` it.



YouTube Videos


They can't be added directly but you can add an image with a link to the video like this:

<a href="http://www.youtube.com/watch?feature=player_embedded&v=YOUTUBE_VIDEO_ID_HERE
" target="_blank"><img src="http://img.youtube.com/vi/YOUTUBE_VIDEO_ID_HERE/0.jpg" 
alt="IMAGE ALT TEXT HERE" width="240" height="180" border="10" /></a>


https://stackoverflow.com/questions/33023349/atom-disable-single-key-binding
  1. Open settings with File > Settings
  2. Click Keybindings
  3. Filter the list by typing ctrl-alt-= in the search box.
  4. Click the clipboard icon next to the shortcut. This will copy the shortcut definition to your clipboard.
  5. Click the hyperlinked text your keymap file.
  6. Paste in the contents of the clipboard.
  7. Replace 'pane:increase-size' with the value 'unset!'

Keymap

  • How to disable key binding
    • Click the clipboard to copy the shortcut definition in Keybindings settings
    • replace the function to unset! to remove it or change it to another function

Solve the conflict between jumpy:toggle and markdown-preview-enhanced:run-code-chunk

'.editor[data-grammar*="gfm"], .editor[data-grammar*="md"], .editor[data-grammar*="markdown"]':
  'shift-enter': 'jumpy:toggle'
https://stackoverflow.com/questions/12145232/create-an-automatically-numbered-list
That should happen automatically (at least in SO flavored MD):
  1. test 1
  2. test 2
The code I used it:
1. test 1
1. test 2
The same works for GitHub flavored MD: https://gist.github.com/3489721
https://imagemagick.org/script/download.php
sudo port install ImageMagick

https://blog.github.com/2014-04-28-task-lists-in-all-markdown-documents/
- [ ] Mercury
- [x] Venus
- [x] Earth (Orbit/Moon)

https://markdown-here.com/
Write your email in Markdown, then make it pretty.
Hashify: Read about it at http://hashify.me/
Socrates: Read about it at http://socrates.io/

Some blog platforms, such as Tumblr, have an editor that supports writing in Markdown.
Another option is to use static site generators such as Jekyll, Octopress, or nanoc. This way we can transform plain text files into static web pages and blogs.


reveal.js: Check this out at http://lab.hakim.se/reveal-js/
deck.js: Check this out at http://imakewebthings.com/deck.js/
In reveal.js, each section represents one slide, so we can write slides in plain text using Markdown:

<section data-markdown>
    <script type="text/template">
        ## Page title

        A paragraph with some text and a [link](http://hakim.se).
    </script>
</section>

<section data-markdown>
    <script type="text/template">
        ## New slide

        Presentations made **easy**
    </script>
</section>

For the two top-level headers (the <h1> and <h2> tags), there is a special syntax that can be used:

Header 1
========

Header 2
--------

Pandoc
       By default, pandoc produces a document fragment.  To produce a standalone document (e.g.  a valid HTML file including <head> and <body>), use the -s or --standalone flag:
       The format of the input and output can be specified explicitly using command-line options.  The input format can be specified using the -f/--from option, the output format using the -t/--to option.  Thus, to

https://stackoverflow.com/questions/30880200/pandoc-what-are-the-available-syntax-highlighters
pandoc --bash-completion

If --bash-completion works, then put this line towards the end of your ${HOME}/.bashrc file (on Mac OS X or Linux -- doesn't work on Windows yet):

eval "$(pandoc --bash-completion)"



  pandoc --list-highlight-styles



  pandoc --list-highlight-languages



  pandoc --list-input-formats
  pandoc --list-output-formats
  pandoc --list-extensions

Once you decided which style was the closest to your need, you can output its theme file, using (for instance for pygments, the default style):
pandoc --print-highlight-style pygments
so that you can store this style in a file, using, e.g.,
pandoc --print-highlight-style pygments > my_style.theme

pandoc my_file.md --highlight-style my_style.theme -o doc.html

https://github.com/benweet/stackedit/issues/285
The postID can be found in the URL of the pencil icon at the bottom of a post when it is viewed at blogger.com, if you are logged in as the blog's owner.
You can sync Markdown documents to Google Drive from within Stack Edit for backup or export them to GoogleDocs as fully-formatted files. These exported files can then be further edited and shared in Google Docs like native files, allowing you to start writing in Markdown but share fully-formatted files. The export is a one-way process, unfortunately. Edits you make in Google Docs won’t be ported back into your Markdown file.

You can use gdocs2md, an open-source Google Docs script that converts files from Google Docs format to Markdown

Markdown allows you to include raw HTML
To insert inline code, we wrap it with backticks (`and`):
Type `echo 'Hello World'` in your terminal

The embedding of pre-formatted code blocks is possible by indenting every line of the block with four spaces or one tab:

    echo 'Hello World'

https://stackoverflow.com/questions/20303826/highlight-bash-shell-code-in-markdown
Rendered on GitHub, console makes the lines after the console blue. bashsh, or shell don't seem to "highlight" much ...and you can use posh for PowerShell or CMD.
Pandoc
       By default, pandoc produces a document fragment.  To produce a standalone document (e.g.  a valid HTML file including <head> and <body>), use the -s or --standalone flag:
       The format of the input and output can be specified explicitly using command-line options.  The input format can be specified using the -f/--from option, the output format using the -t/--to option.  Thus, to
https://stackoverflow.com/questions/23811002/from-markdown-to-pdf-how-to-change-the-font-size-with-pandoc
-V fontsize=12pt
For new users of pandoc (like myself), as an alternative to specifying variables with the -V flag, you can add them to the YAML metadata block of the markdown file. To change the fontsize, prepend following to your markdown document.
---
fontsize: 12pt
---
Works with fontsize 10,11, and 12. In addition to the comments on John MacFarlane's answer, there is some good info on specifying additional fontsizes with latex in this article (inline latex can be used in pandoc markdown documents being converted to pdf).
If you want to go bigger than 12pt you can use the extsizes package. Was already pre installed for me, so this worked out of the box with pandoc:
---
documentclass: extarticle
fontsize: 14pt
---

…
Possible sizes are 8pt, 9pt, 10pt, 11pt, 12pt, 14pt, 17pt, 20pt.

If you use --standalone 

you'll get a style tag with a link. 

If you use --self-contained 

you'll get a data: URL. 
http://pandoc.org/MANUAL.html#extension-yaml_metadata_block

Extension: yaml_metadata_block

A YAML metadata block is a valid YAML object, delimited by a line of three hyphens (---) at the top and a line of three hyphens (---) or three dots (...) at the bottom. A YAML metadata block may occur anywhere in the document, but if it is not at the beginning, it must be preceded by a blank line. <<



https://www.javacodegeeks.com/2016/03/converting-markdown-pdf-docx-pandoc.html

Pandoc is able to merge multiple Markdown files into a single PDF document. To generate a single PDF document out of two Markdown files you can use:
1pandoc -s -o doc.pdf part01.md part02.md
By default the page margins in the resulting PDF document are quite large. You can change this by passing a margin parameter:
1pandoc -s -V geometry:margin=1in -o documentation.pdf part01.md part02.md
http://pandoc.org/MANUAL.html#linked-media

Extension: backtick_code_blocks

Same as fenced_code_blocks, but uses backticks (`) instead of tildes (~).

https://gist.github.com/atelierbram/09c8fb742f1518f09ff9e4338ab8f7fb
  pandoc -f markdown -t html5 -o output.html input.md -c style.css

https://stackoverflow.com/questions/12311344/pandoc-converting-markdown-to-html-syntax-highlighter
You don't need an external extension. Just be sure to use the -s flag so you get a standalane HTML file with the CSS needed for highlighting. You can also use the --highlight-style option to adjust the coloring scheme

https://stackoverflow.com/questions/6695439/how-to-link-to-a-named-anchor-in-multimarkdown
In standard Markdown, place an anchor <a name="abcd"></a> where you want to link to and refer to it on the same page by [link text](#abcd).
(This uses name= and not id=, for reasons explained in this answer.)
Remote references can use [link text](http://...#abcd) of course.
This works like a dream, provided you have control over the source and target texts. The anchor can even appear in a heading, thus:
### <a name="head1234"></a>A Heading in this SO entry!
https://www.toketaware.com/makeslides/

https://pandoc.org/MANUAL.html#producing-slide-shows-with-pandoc
By default, the slide level is the highest header level in the hierarchy that is followed immediately by content, and not another header, somewhere in the document. In the example above, level 1 headers are always followed by level 2 headers, which are followed by content, so 2 is the slide level. This default can be overridden using the --slide-level option.
The document is carved up into slides according to the following rules:
  • A horizontal rule always starts a new slide.
  • A header at the slide level always starts a new slide.
  • Headers below the slide level in the hierarchy create headers within a slide.
  • Headers above the slide level in the hierarchy create “title slides,” which just contain the section title and help to break the slide show into sections.
  • Content above the slide level will not appear in the slide show.
  • A title page is constructed automatically from the document’s title block, if present. (In the case of beamer, this can be disabled by commenting out some lines in the default template.)

https://www.infoworld.com/article/3186253/application-development/coders-heres-a-javascript-presentation-tool-youll-love.html
https://github.com/gnab/remark/issues/363

https://rmarkdown.rstudio.com/beamer_presentation_format.html

https://www.chronicle.com/blogs/profhacker/markdown-slideshow-example-pandoc/46683
Pandoc has built-in support for the conversion of markdown (and a range of other simple text markup) into several browser friendly slideshow formats. These include DZSlidesS5Slidy, and Slideous (if you know LaTeX, beamertoo). Many of these offer a shortcut to display a table of contents and Slideous offers a shortcut to easily change the font size.
pandoc -t FORMAT -s habits.txt -o habits.html
where FORMAT is either s5slidyslideousdzslides, or revealjs.
https://github.com/jgm/pandoc/wiki/Using-pandoc-to-produce-reveal.js-slides

brew install pandoc
pandoc -f markdown -t latex hello.txt
To convert hello.html from HTML to Markdown:
pandoc -f html -t markdown hello.html
To produce a PDF slide show using beamer, type
pandoc -t beamer habits.txt -o habits.pdf
Note that a reveal.js slide show can also be converted to a PDF by printing it to a file from the browser.
To produce a Powerpoint slide show, type
pandoc habits.txt -o habits.pptx

http://aiyanbo.github.io/md-ppt/player.html
  1. 打开播放器程序 http://aiyanbo.github.io/md-ppt/player.html
  2. 将 markdown 文件拖入 "Drop markdown file" 框中
https://daringfireball.net/projects/markdown/
https://gitpitch.com/
https://github.com/gnab/remark/issues/30

  1. remove <textarea id="source"> ... </textarea>
  2. Use the code above in place of the existing code at the bottom: <script> var slideshow = remark.create(); </script>
$ cd MarkdownFolder
$ python -m SimpleHTTPServer
Now, a webserver will be running on port 8000 on your machine, accessable via http://localhost:8000. If MarkdownFolder contains your index.html and index.markdown files, you can go to http://localhost:8000/index.html without having to bother with the --allow-file-access-from-filesoption you found
https://remarkjs.com/#1


To render your Markdown-based slideshow on the fly, checkout Remarkise.
  • Markdown formatting, with smart extensions
  • Presenter mode, with cloned slideshow view
  • Syntax highlighting, supporting a range of languages

Slide properties, for naming, styling and templating slides

Content classes, for styling specific content

Syntax highlighting, supporting a range of languages
Initial lines containing key-value pairs are extracted as slide properties:
name: agenda
class: middle, center
# Agenda
The name of this slide is {{ name }}.

Pressing P will toggle presenter mode.


Creating a cloned view of your slideshow lets you:

Move the cloned view to the extended display visible to the audience

Put the original slideshow in presenter mode

Navigate as usual, and the cloned view will automatically keep up with the original

Pressing C will open a cloned view of the current slideshow in a new browser window.
https://github.com/gnab/remark/wiki/Markdown#slide-properties

Incremental Slides

To avoid having to duplicate content if a slide is going to add to the previous one, using only two dashes to separate slides will make a slide inherit the content of the previous one:
# Slide

- bullet 1
--

- bullet 2
https://pandoc.org/

Gaia theme
Marp uses the horizontal ruler to create multi-page slides. A --- between empty lines splits the presentation into slides. This format is similar to Deckset.

Marp’s Markdown has extended directives to affect slides. Insert HTML comment as <!-- {directive_name}: {value} -->
Show example.md 

You can resize slides with the Global Directive $size. Insert <!-- $size: 16:9 --> if you want to display slides on 16:9 screen. That’s all!
<!-- $size: 16:9 -->
$size directive supports 4:316:9A0-A8B0-B8 and the -portraitsuffix.
Marp also supports $width and $height directives to set a custom size.

You want pagination? Insert <!-- page_number: true --> at the top.
If you want to exclude the first page number, move the directive to after the first ruler.
# First page

The page number `1` is not shown.

---
<!-- page_number: true -->

# Second page

The page number `2` is shown!
https://stackoverflow.com/questions/24887301/is-there-a-syntax-for-links-with-no-text-in-markdown

AUTOMATIC LINKS

Markdown supports a shortcut style for creating “automatic” links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
<http://example.com/>

https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#tables
| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|fF
| col 3 is      | right-aligned | $1600 |
https://stackoverflow.com/questions/17536216/create-table-without-header-in-markdown/39322697#39322697
markdown table without header
If you don't mind wasting a line by leaving it empty, then can live with the following hack as of now. (As I said it is a hack, and use this only if you don't like adding any additional plugins)
| | | |
|-|-|-|ff
| Normal Key| Value1 |
|__BoldKey__| Value2 |


https://stackoverflow.com/questions/37575916/how-to-markdown-nested-list-items-in-bitbucket

Use 4 spaces

----------------
# using 4 spaces
----------------

# Unordered list

* Item 1
* Item 2
* Item 3
    * Item 3a
    * Item 3b
    * Item 3c

target="_blank"
https://gist.github.com/shaunlebron/746476e6e7a4d698b373
also causes line break.
http://markdown-guide.readthedocs.io/en/latest/basics.html#line-return
Creating simple lists is done by using plus, hyphens or asterisks as list markers. These list markers are interchangeable.
Markdown:
+ One
- Two
* Three
Nest a list requires you to indent by exactly four spaces.
Markdown:
+ One
+ Two
+ Three
    - Nested One
    - Nested Two
A paragraph is one or more consecutive lines of text separated by one or more blank lines. Normal paragraphs should not be indented with spaces or tabs.


To force a line return, place two empty spaces at the end of a line.
Inline-style links use parentheses immediately after the link text.
Markdown:
This is an [example link](http://example.com/).
This is an [example link](http://example.com/ "With a Title").
https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet

http://reeoo.me/archives/markdown.html
  1. 专注于你写作的内容本身,而不是排版样式。
  2. 可以导出 HTML、PDF 和本身的 .md 文件。
  3. 纯文本内容,兼容所有的文本编辑器与字处理软件。
  4. 随时修改你的文章版本,不必像字处理软件生成若干文件版本导致混乱。
  5. 可读、直观、学习成本低。
文章内容较多时,可以用标题分段:
# 标题1
## 标题2
### 标题3
#### 标题4
##### 标题5
###### 标题6

粗体和斜体

*斜体文本*  或者  _斜体文本_
**粗体文本**   或者 __粗体文本__
***粗斜体文本***  或者  ___粗斜体文本___

文字链接 Reeoo’s Blog
网址链接 http://reeoo.me
文字链接 [链接名称](http://链接网址)
网址链接 <http://链接网址>
高级链接技巧
这个链接用 me 作为网址变量 [ReeooMe][me]
这个链接用 co 作为网址变量 [ReeooCo][co]
然后在文档的结尾为变量赋值(网址)
[me]: http://reeoo.me/
[co]: http://reeoo.co/
普通无序列表
- 列表文本前使用 [减号+空格]
+ 列表文本前使用 [加号+空格]
* 列表文本前使用 [星号+空格]

普通有序列表
1. 列表前使用 [数字+空格]
2. 我们会自动帮你添加数字
7. 不用担心数字不对,显示的时候我们会自动把这行的 7 纠正为 3

普通引用
> 引用文本前使用 [大于号+空格]
> 折行可以不加,新起一行都要加上哦

引用里嵌套引用
语法:
> 最外层引用
> > 多一个 > 嵌套一层引用
> > > 可以嵌套很多层

引用里嵌套列表
语法:
> - 这是引用里嵌套的一个列表
> - 还可以有子列表
>     * 子列表需要从 - 之后延后四个空格开始


跟链接的方法区别在于前面加了个感叹号 !,这样是不是觉得好记多了呢?
语法:![图片名称](http://图片网址)
当然,你也可以像网址那样对图片网址使用变量
这个链接用 me 作为网址变量 [Reeoo's Blog][me].
然后在文档的结尾位变量赋值(网址)
[me]: http://img.reeoo.me/compass/add.jpg
分隔符
如果你有写分割线的习惯,可以新起一行输入三个减号-。当前后都有段落时,请空出一行:
写法:
前面的段落

---

后面的段落

表格

表格是我觉得 Markdown 比较累人的地方,例子如下:


1
2
3
4
5
| Tables        | Are           | Cool  |
|:------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

如果你只想高亮语句中的某个函数名或关键字,可以使用 `function_name()` 实现(function_name())
通常编辑器根据代码片段适配合适的高亮方法,但你也可以用 ``` 包裹一段代码,并指定一种语言


1
2
3
$(function () {
    console.log('reeoo.me');
});

支持的语言:actionscriptapachebashclojurecmakecoffeescriptcppcscssddelphidjangoerlang,gohaskellhtmlhttpinijavajavascriptjsonlispluamarkdownmatlabnginxobjectivecperl,phppythonrrubyscalasmalltalksqltexvbscriptxml
也可以使用 4 空格缩进,再贴上代码,实现相同的的效果
nodeppt:用markdown写ppt

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts