根据 用Golang实现 服务器/客户端 将其改造成一个文本信息聊天室

服务端的改动

  1. 服务器为了实现聊天信息的群体广播, 需要记录所有连接到服务器的客户端信息, 所以, 我们需要添加一个集合来保存所有客户端的连接:

    var ConnMap map[string]*net.TCPConn
    
  2. 接着, 每次当有新的客户端连接到服务器时, 需要把这个客户端连接行信息加入集合:

    ConnMap[tcpConn.RemoteAddr().String()] = tcpConn
    
  3. 当服务器收到客户端的聊天信息时, 需要广播到所有客户端, 所以我们需要利用上面保存TCPConn的map来遍历所有TCPConn进行广播, 用以下方法实现:

阅读更多

服务端的实现思路及步骤

  1. 创建一个套接字对象, 指定其IP以及端口
  2. 开始监听套接字指定的端口
  3. 如有新的客户端连接请求, 则建立一个goroutine, 在goroutine中, 读取客户端消息, 并转发回去, 直到客户端断开连接
  4. 主进程继续监听端口

阅读更多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import (
"bufio"
"fmt"
"io/ioutil"
"os"
)

func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
d1 := []byte("hello\ngo\n")
err := ioutil.WriteFile("/tmp/dat1", d1, 0644)
check(err)
f, err := os.Create("/tmp/dat2")
check(err)
defer f.Close()

d2 := []byte{115, 111, 109, 101, 10}
n2, err := f.Write(d2)
check(err)
fmt.Printf("wrote %d bytes\n", n2)

n3, err := f.WriteString("writes\n")
fmt.Printf("wrote %d bytes\n", n3)
f.Sync()
w := bufio.NewWriter(f)

n4, err := w.WriteString("buffered\n")
fmt.Printf("wrote %d bytes\n", n4)
w.Flush()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
	
$ go run writing-files.go
wrote 5 bytes
wrote 7 bytes
wrote 9 bytes

$ cat /tmp/dat1
hello
go
$ cat /tmp/dat2
some
writes
buffered

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import s "strings"
import "fmt"

var p = fmt.Println

func main() {
p("Contains: ", s.Contains("test", "es"))
p("Count: ", s.Count("test", "t"))
p("HasPrefix: ", s.HasPrefix("test", "te"))
p("HasSuffix: ", s.HasSuffix("test", "st"))
p("Index: ", s.Index("test", "e"))
p("Join: ", s.Join([]string{"a", "b"}, "-"))
p("Repeat: ", s.Repeat("a", 5))
p("Replace: ", s.Replace("foo", "o", "0", -1))
p("Replace: ", s.Replace("foo", "o", "0", 1))
p("Split: ", s.Split("a-b-c-d-e", "-"))
p("ToLower: ", s.ToLower("TEST"))
p("ToUpper: ", s.ToUpper("test"))
p()
p("Len: ", len("hello"))
p("Char:", "hello"[1])
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ go run string-functions.go
Contains: true
Count: 2
HasPrefix: true
HasSuffix: true
Index: 1
Join: a-b
Repeat: aaaaa
Replace: f00
Replace: f0o
Split: [a b c d e]
toLower: test
ToUpper: TEST
Len: 5
Char: 101

  毫无疑问,随着互联网、移动网络接入成本的降低,互联网正在日益深入地走入我们的生活,越来越成为人们获取信息的高效平台,ICP行业也顺势呈现出强劲的成长趋势,成为互联网迅猛发展形势下最大的受益者,也直接促成了从web1.0到web2.0以及社区、博客、视频等一系列互联网时代的更迭和运营模式的变动。

  但是随着各站点访问量和信息交流量的迅猛增长,如何使用最小的资源成本,提高网络的效率,最优化用户体验,已经成为网络管理人员不得不面对的挑战。

  从技术上讲,就是ICP行业面临的网络资源有效利用问题,也就是如何进行对网络的访问分流,以便能够快速响应用户反应,即:负载均衡。

阅读更多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)

// http get by proxy
func GetByProxy(url_addr, proxy_addr string) (*http.Response, error) {
request, _ := http.NewRequest("GET", url_addr, nil)
proxy, err := url.Parse(proxy_addr)
if err != nil {
return nil, err
}
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxy),
},
}
return client.Do(request)
}

func main() {
proxy := "http://58.252.56.149:9000/"
url := "http://www.baidu.com/"
resp, _ := GetByProxy(url, proxy)
fmt.Println(resp)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}

本文引自这里

快速排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package main

import (
"fmt"
)

func quickSort(values []int, left int, right int) {
if left < right {

// 设置基准值
temp := values[left]

// 设置哨兵
i, j := left, right
for {
// 从右向左找,找到第一个比基准值小的数
for values[j] >= temp && i < j {
j--
}

// 从左向右找,找到第一个比基准值大的数
for values[i] <= temp && i < j {
i++
}

// 如果哨兵相遇,则退出循环
if i >= j {
break
}

// 交换左右两侧的值
values[i], values[j] = values[j], values[i]
}

// 将基准值移到哨兵相遇点
values[left] = values[i]
values[i] = temp

// 递归,左右两侧分别排序
quickSort(values, left, i-1)
quickSort(values, i+1, right)
}
}

func QuickSort(values []int) {
quickSort(values, 0, len(values)-1)
}

冒泡排序

1
2
3
4
5
6
7
8
9
func BubbleSort(values []int) {
for i := 1; i < len(values); i++ {
for j := 0; j < len(values)-i; j++ {
if values[j] > values[j+1] {
values[j], values[j+1] = values[j+1], values[j]
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
arr := []int{3, 7, 9, 8, 38, 93, 12, 222, 45, 93, 23, 84, 65, 2}
QuickSort(arr)
fmt.Println(arr)

// 结果
[2 3 7 8 9 12 23 38 45 65 84 93 93 222]

arr2 := []int{3, 7, 9, 8, 38, 93, 12, 222, 45, 93, 23, 84, 65, 2}
BubbleSort(arr2)
fmt.Println(arr2)

// 结果
[2 3 7 8 9 12 23 38 45 65 84 93 93 222]

优化从kafka中取用户日志

最初是根据开始时间,结束时间从kafka提供的api中取出json数据,然后挨个解析判断是否符合条件。

由于数据量很大,这种方式会特别慢。

初步优化

通过kakfa官方提供的命令行工具,取出用户日志,然后再利用系统grep命令筛选出符合条件的数据,此时数据为json流,之后将json流数据循环解析过滤出最终数据

阅读更多

读写锁是针对于读写操作的互斥锁。

基本遵循两大原则:

1、可以随便读。多个gorouting同时读。

2、写的时候,啥都不能干。不能读,也不能写。

解释:

在32位的操作系统中,针对int64类型值的读操作和写操作不可能只由一个CPU指令完成。如果一个写的操作刚执行完了第一个指令,时间片换给另一个读的协程,这就会读到一个错误的数据。

阅读更多