1.1:修改echo程序输出os.Args[0],即命令的名称。 
package main
import(
	"fmt"
	"os"
)
func main(){
	for i 
:= 1; i 
< len(os
.Args
);i
++{
		fmt
.Println(os
.Args
[i
])
	}
}
 
go run main.go monther father sun
 
monther
father
sun
 
1.2:修改echo程序,输出参数的索引和值,每行一个 
package main
import (
	"fmt"
	"os"
)
func main(){
	for i 
:= 1; i 
< len(os
.Args
); i
++{
		fmt
.Println(i
)
		fmt
.Println(os
.Args
[i
])
	}
}
 
go run main.go monther father sun
 
1
monther
2
father
3
sun
 
1.3:尝试测量可能低效的程序和使用strings.Join的程序在执行时间上的差异。 
package main
import(
			"fmt"
			"os"
			"time"
)
func echo1(){
	start 
:= time
.Now()
	var s
, sep 
string
	for i 
:= 1; i 
< len(os
.Args
); i
++{
		s 
+= sep 
+ os
.Args
[i
]
		sep 
= " "
	}
	fmt
.Println(s
)
	secs 
:= time
.Since(start
).Seconds()
	fmt
.Println(secs
)
}
func echo2(){
	start 
:= time
.Now()
	s
, sep 
:= "", ""
	for _, arg 
:= range os
.Args
[1:]{
		s 
+= sep 
+ arg
		sep 
= " "
	}
	fmt
.Println(s
)
	secs 
:= time
.Since(start
).Seconds()
	fmt
.Println(secs
)
}
func echo3(){
	start 
:= time
.Now()
	fmt
.Println(strings
.Join(os
.Args
[1:]," "))
	secs 
:= time
.Since(start
).Seconds()
	fmt
.Println(secs
)
}
func main(){
	echo1()
	echo2()
	echo3()
}
 
go run main.go mother father sun
 
mohter father son
2.9647e-05
mohter father son
1.704e-06
mohter father son
1.648e-06
 
1.4:修改dup2程序,输出出现重复行的文件的名称。 
func dup2(){
	counts 
:= make(map[string]int)
	files 
:= os
.Args
[1:]
	if len(files
) == 0{
		countLines(os
.Stdin
, counts
)
	}else{
		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()
		}
	}
	for line
, n 
:= range counts
{
		if n 
> 1{
			fmt
.Printf("%d\t%s\n", n
, line
)
		}
	}
}
func countLines(f 
*os
.File
, counts 
map[string]int){
	input 
:= bufio
.NewScanner(f
)
	for input
.Scan(){
		if counts
[input
.Text()] > 1{
			fmt
.Printf("%s\n",f
.Name())
		}
		counts
[input
.Text()]++
	}
}
func main(){
	dup2()
}
 
1.5:将Lissajous程序的调色板更改为黑色上绿色,以增加真实性。要创建Web颜色#RRGGBB,请使用color.RGBA {0xRR,0xGG,0xBB,0xff},其中每对十六进制数字代表红色的强度, 像素的绿色或蓝色分量。 
var palette 
= []color
.Color
{color
.RGBA
{127, 255, 170,255}, color
.Black
}
const(
	whiteIndex 
= 0
	blackIndex 
= 1
)
func lissajous(out io
.Writer
){
	const(
		cycles 
= 5
		res 
= 0.001
		size 
= 100
		nframes 
= 64
		delay 
= 8
	)
	freq 
:= rand
.Float64() * 3.0
	anim 
:= gif
.GIF
{LoopCount
: nframes
}
	phase 
:= 0.0
	for i 
:= 0; i 
< nframes
; i
++{
		rect 
:= image
.Rect(0, 0, 2*size
+1, 2*size
+1)
		img 
:= image
.NewPaletted(rect
, palette
)
		for t 
:= 0.0; t 
< cycles
*2*math
.Pi
; t 
+= res 
{
			x 
:= math
.Sin(t
)
			y 
:= math
.Sin(t
*freq 
+ phase
)
			img
.SetColorIndex(size
+int(x
*size
+0.5), size
+int(y
*size
+0.5), blackIndex
)
		}
		phase 
+= 0.1
		anim
.Delay 
= append(anim
.Delay
, delay
)
		anim
.Image 
= append(anim
.Image
, img
)
	}
	gif
.EncodeAll(out
, &anim
)
}
func main(){
	lissajous(os
.Stdout
)
}
 
1.6:修改Lissajous程序,以通过向调色板中添加更多值,然后通过以一些有趣的方式更改SetColorIndex的第三个参数来显示它们来生成多种颜色的图像。 
修改调色盘里的参数就可以了。
 
1.7: 函数io.Copy(dst, src)从src读,并且写入dst。使用它代替ioutil.ReadAll来复制响应内容到os.Stdout,这样不需要装下整个响应数据流的缓冲区。确保检查io.Copy返回的错误结果。 
func fetch(){
	for _, url 
:= range os
.Args
[1:]{
		resp
, err 
:= http
.Get(url
)
		if err 
!= nil{
			fmt
.Fprintf(os
.Stderr
, "fetch: %v\n", err
)
			os
.Exit(1)
		}
		_, err 
= io
.Copy(os
.Stdout
, resp
.Body
)
		resp
.Body
.Close()
		if err 
!= nil {
			fmt
.Fprintf(os
.Stderr
, "fetch: reading %s: %v\n", url
, err
)
			os
.Exit(1)
		}
	}
}
func main(){
	fetch()
}
 
1.8:修改fetch程序添加一个http://前缀(假设该URL参数缺失协议前缀)。可能会用到strings.HasPrefix。 
func fetch(){
	for _, url 
:= range os
.Args
[1:]{
		if !strings
.HasPrefix(url
, "http://"){
			url 
= "http://" + url
		
}
		resp
, err 
:= http
.Get(url
)
		if err 
!= nil {
			fmt
.Fprintf(os
.Stderr
, "fetch: %v\n", err
)
			os
.Exit(1)
		}
		b
, err 
:= ioutil
.ReadAll(resp
.Body
)
		resp
.Body
.Close()
		if err 
!= nil{
			fmt
.Fprintf(os
.Stderr
, "fetch: reading %s: %v\n", url
, err
)
			os
.Exit(1)
		}
		fmt
.Printf("%s",b
)
	}
}
func main(){
	fetch()
}
 
1.9:修改fetch来输出HTTP的状态码,可以在resp.Status中找到它。 
func fetch(){
	for _, url 
:= range os
.Args
[1:]{
		if !strings
.HasPrefix(url
, "http://"){
			url 
= "http://" + url
		
}
		resp
, err 
:= http
.Get(url
)
		if err 
!= nil {
			fmt
.Fprintf(os
.Stderr
, "fetch: %v\n", err
)
			os
.Exit(1)
		}
		fmt
.Printf("%s\n",resp
.Status
)
		
		resp
.Body
.Close()
		if err 
!= nil{
			fmt
.Fprintf(os
.Stderr
, "fetch: reading %s: %v\n", url
, err
)
			os
.Exit(1)
		}
		
	}
}
func main(){
	fetch()
}
 
1.10:找一个产生大量数据的网站。连续两次运行fetchall,看报告的时间是否会有很大的变化,调查缓存情况。每一次获取的内容一样吗?修改fetchall将内容输出到文件,这样可以检查它是否一致。 
func fetchall(){
	start 
:= time
.Now()
	ch 
:= make(chan string)
	for _, url 
:= range os
.Args
[1:]{
		go fetch(url
, ch
)
	}
	for range os
.Args
[1:]{
		fmt
.Println(<-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
)
		return
	}
	b
, _ := ioutil
.ReadAll(resp
.Body
)
	nbytes
, err 
:= io
.Copy(ioutil
.Discard
, resp
.Body
)
	resp
.Body
.Close()
	if err 
!= nil {
		ch 
<- fmt
.Sprintf("while reading %s: %v", url
, err
)
		return
	}
	secs 
:= time
.Since(start
).Seconds()
	ch 
<- fmt
.Sprintf("%.2fs } %s\n %s", secs
, nbytes
, url
, b
)
}
func main(){
	fetchall()
}
 
我ping的是百度,时间不一样,内容一样的,内容具体我也没怎么比较,就滚了一下。
 
1.11:使用更长的参数列表来尝试fetchall,例如使用alexa.com排名前100万的网站。如果一个网站没有响应,程序的行为是怎样的? 
ye@yewenweis-MacBook-Pro src % ./1 https://golang.org http://gopl.io http://godoc.org
1.47s    7510 http://godoc.org
 %!s(MISSING)
Get "http://www.gopl.io/": dial tcp [::1]:80: connect: connection refused
Get "https://golang.org": dial tcp 216.239.37.1:443: i/o timeout
30.01s elapsed
 
[旺柴]书上的网站就进不去。
 
1.12:修改Lissajous服务器以从URL读取参数值。 例如,您可以进行排列,以使诸如http:// localhost:8000 /?cycles = 20之类的URL将循环数设置为20,而不是默认值5。使用strconv.Atoi函数将字符串参数转换为 整数。您可以通过go doc strconv.Atoi查看其文档。 
package main
import (
	"fmt"
	"image"
	"image/color"
	"image/gif"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
)
var palette 
= []color
.Color
{color
.RGBA
{127, 255, 170,255}, color
.Black
}
const(
	whiteIndex 
= 0
	blackIndex 
= 1
)
func lissajous(out io
.Writer
){
	const(
		cycles 
= 5
		res 
= 0.001
		size 
= 100
		nframes 
= 64
		delay 
= 8
	)
	freq 
:= rand
.Float64() * 3.0
	anim 
:= gif
.GIF
{LoopCount
: nframes
}
	phase 
:= 0.0
	for i 
:= 0; i 
< nframes
; i
++{
		rect 
:= image
.Rect(0, 0, 2*size
+1, 2*size
+1)
		img 
:= image
.NewPaletted(rect
, palette
)
		for t 
:= 0.0; t 
< cycles
*2*math
.Pi
; t 
+= res 
{
			x 
:= math
.Sin(t
)
			y 
:= math
.Sin(t
*freq 
+ phase
)
			img
.SetColorIndex(size
+int(x
*size
+0.5), size
+int(y
*size
+0.5), blackIndex
)
		}
		phase 
+= 0.1
		anim
.Delay 
= append(anim
.Delay
, delay
)
		anim
.Image 
= append(anim
.Image
, img
)
	}
	gif
.EncodeAll(out
, &anim
)
}
func handler(w http
.ResponseWriter
, r 
*http
.Request
){
	fmt
.Fprintf(w
, "%s %s %s\n", r
.Method
, r
.URL
, r
.Proto
)
	for k
, v 
:= range r
.Header
{
		fmt
.Fprintf(w
, "Header[%q] = %q\n", k
, v
)
	}
	fmt
.Fprintf(w
, "host = %q\n", r
.RemoteAddr
)
	if err 
:= r
.ParseForm(); err 
!= nil{
		log
.Print(err
)
	}
	for k
, v 
:= range r
.Form
{
		fmt
.Fprintf(w
, "Form[%q] = %q\n", k
, v
)
	}
}
func main(){
	http
.HandleFunc("/", func(w http
.ResponseWriter
, r 
*http
.Request
){
		lissajous(w
)
	})
	log
.Fatal(http
.ListenAndServe("localhost:8000", nil))
}
 
只能输出gif,但不知道怎么修改题目要求那个东西。有大佬做出来告诉一下。