通讯[1][2]

  1. 编写一个程序,列出所有正在运行的进程,并打印每个进程执行的子进 程个数。
package main

import (
    "fmt"
    "os/exec"
    "sort"
    "strconv"
    "strings"
)

func main() {
    ps := exec.Command("ps", "-e", "-opid,ppid,comm")

    output, _ := ps.Output()

    child := make(map[int][]int)

    for i, s := range strings.Split(string(output), "\n") {
        if i == 0 || len(s) == 0 {
            continue
        }

        f := strings.Fields(s)

        fpp, _ := strconv.Atoi(f[1])

        fp, _ := strconv.Atoi(f[0])

        child[fpp] = append(child[fpp], fp)

    }

    schild := make([]int, len(child))

    i := 0
    for k, _ := range child {
        schild[i] = k
        i ++
    }
    sort.Ints(schild)
    for _, ppid := range schild {
        fmt.Printf("Pid %d has %d child", ppid, len(child[ppid ]))

        if len(child[ppid]) == 1 {
            fmt.Printf(": %v\n", child[ppid])

            continue
        }

        fmt.Printf("ren: %v\n", child[ppid])
    }

}
  1. 单词和字母统计。
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {

    var chars, words, lines int

    r := bufio.NewReader(os.Stdin)


    for {
        switch s, ok := r.ReadString('\n'); true {
        case ok != nil:
            //处理错误
            fmt.Printf("%d %d %d\n", chars, words, lines); return
        default:
            chars += len(s)
            words += len(strings.Fields(s))
            lines++

        }
    }
}
  1. 编写一个 Go 程序模仿 Unix 命令 uniq 的功能。
package main

import "fmt"

func main () {
    s := []string {"a", "b", "a", "a", "c", "d", "e", "f"}

    first := s[0]

    fmt.Printf("%s ", first)

    for _, str := range s[1:] {
        if first != str {
            fmt.Printf("%s ", str)

            first = str
        }
    }
}
  1. 用 Go 编写一个 Quine 程序。

package main

import "fmt"

func main() {
    fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
}

var q = `/* Go quine */ 
package main 
import "fmt" 
func main(){ 
    fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60) 
} 
var q = `
  1. Echo 服务。
package main

import (
    "bufio"
    "fmt"
    "net"
)

func main() {
    n, err := net.Listen("tcp", "127.0.0.1:8053")

    if err != nil {
        fmt.Print("服务运行失败", err.Error())
    }

    for ; ; {
        //通过net获取到connection
        if c, err := n.Accept(); err == nil {
            //并发处理,每个请求都可以在独立的 goroutine 中进行处理
            go Echo(c)
        }
    }

}

//传递一个链接进来
func Echo(c net.Conn) {
    defer c.Close()
    //读取数据
    line, err := bufio.NewReader(c).ReadString('\n')

    if err != nil {
        fmt.Printf("Failure to read: %s\n", err.Error())

        return
    }
    //读取到数据后马上又打印出来
    _, e := c.Write([]byte(line))

    if e != nil {
        fmt.Printf("Failure to write: %s\n", err.Error())

        return
    }
}
  1. 数字游戏。
package main

import (
	"flag"
	"fmt"
	"strconv"
)

const (
	_ = 1000 * iota

	ADD
	SUB
	MUL
	DIV
	MAXPOS = 11
)

var mop = map[int]string{ADD: "+", SUB: "-", MUL: "*", DIV: "/"}

var (
	ok    bool
	value int
)

type Stack struct {
	i    int
	data [MAXPOS]int
}

func (s *Stack) Reset() {
	s.i = 0
}

func (s *Stack) Len() int {
	return s.i
}

func (s *Stack) Push(k int) {

	s.data[s.i] = k
	s.i ++

}

func (s *Stack) Pop() int {

	s.i --
	return s.data[s.i]

}

var found int

var stack = new(Stack)

func main() {

	flag.Parse()

	list := []int{1, 6, 7, 8, 8, 75, ADD, SUB, MUL, DIV}
	//Arg0 是 i
	magic, ok := strconv.Atoi(flag.Arg(0))

	if ok != nil {
		return
	}

	f := make([]int, MAXPOS)

	solve(f, list, 0, magic)

}

func solve(form, numberop []int, index, magic int) {

	var tmp int
	for i, v := range numberop {
		if v == 0 {
			goto NEXT
		}
		if v < ADD {
			tmp = numberop[i]
			numberop[i] = 0
		}
		form[index] = v
		value, ok = rpncalc(form[0 : index+1])

		if ok && value == magic {
			if v < ADD {
				numberop[i] = tmp
			}
			found++
			fmt.Printf("%s = %d  #%d\n",
				rpnstr(form[0:index+1]), value, found)
		}

		if index == MAXPOS-1 {
			if v < ADD {
				numberop[i] = tmp
			}
			goto NEXT
		}
		solve(form, numberop, index+1, magic)
		if v < ADD {
			numberop[i] = tmp
		}
	NEXT:
	}

}

func rpnstr(r []int) (ret string) {
	s := make([]string, 0)

	for k, t := range r {
		switch t {
		case ADD, SUB, MUL, DIV:
			var a, b string
			a, s = s[len(s)-1], s[:len(s)-1]
			b, s = s[len(s)-1], s[:len(s)-1]

			if k == len(r)-1 {
				s = append(s, b+mop[t]+a)
			} else {
				s = append(s, "("+b+mop[t]+a+")")
			}
		default:
			s = append(s, strconv.Itoa(t))
		}
	}

	for _, v := range s {
		ret += v
	}

	return
}

func rpncalc(r []int) (int, bool) {

	stack.Reset()

	for _, t := range r {
		switch t {
		case ADD, SUB, MUL, DIV:

			if stack.Len() < 2 {
				return 0, false
			}
			a := stack.Pop()
			b := stack.Pop()

			if t == ADD {
				stack.Push(b + a)

			}
			if t == SUB {
				if b-a < 0 {
					return 0, false
				}
				stack.Push(b - a)
			}

			if t == MUL {
				stack.Push(b * a)
			}
			if t == DIV {
				if a == 0 {
					return 0, false
				}

				if b%a != 0 {
					return 0, false
				}

				stack.Push(b / a)
			}
		default:
			stack.Push(t)
		}

	}

	if stack.Len() == 1 {
		return stack.Pop(), true
	}

	return 0, false
}

  1. *finger 守护程序。
package main

import (
    "bufio"
    "errors"
    "flag"
    "io/ioutil"
    "net"
    "os/user"
)

func main() {
    flag.Parse()

    ln, err := net.Listen("tcp", ":79")

    if err != nil {
        panic(err)
    }

    for {
        conn, err := ln.Accept()

        if err != nil {
            continue
        }
        go handleConnection(conn)

    }
}

func handleConnection(conn net.Conn) {
    defer conn.Close()

    reader := bufio.NewReader(conn)

    usr, _, _ := reader.ReadLine()

    if info, err := getUserInfo(string(usr)); err != nil {
        conn.Write([]byte(err.Error()))
    } else {
        conn.Write(info)
    }

}

func getUserInfo(usr string) ([]byte, error) {
    u, e := user.Lookup(usr)

    if e != nil {
        return nil, e
    }

    data, err := ioutil.ReadFile(u.HomeDir + ".plan")

    if err != nil {
        return data, errors.New("User doesn't have a .plan file!\n")
    }

    return data, nil
}

完结


  1. 题图出处 ↩︎

  2. 书本链接learning go ↩︎