golang

Go语言之Mysql

package main

import (
   _ "github.com/go-sql-driver/mysql"
   "fmt"
   "database/sql"
)

func main()  {
   //通过mysql驱动连接mysql
   db, err := sql.Open("mysql", "root:111111@tcp(127.0.0.1:3306)/test?charset=utf8")
   if err != nil{
      panic(err)
   }
   //1、插入操作
   stmt1, _ := db.Prepare("insert user_info set username=?,departname=?,createtime=?")
   res1, _ := stmt1.Exec("zhangsan","市场部","2019-2-1")
   id1, _ := res1.LastInsertId()
   fmt.Println(id1)
   //2、更新操作
   stmt2, _ := db.Prepare("update user_info set username=? where id=?")
   res2, _ := stmt2.Exec("lisi",10)
   affected, _ := res2.RowsAffected()
   fmt.Println(affected)
   //3、查询操作
   rows, _ := db.Query("select * from user_info")
   for rows.Next(){
      var id int
      var username string
      var department string
      var createtime string
      err = rows.Scan(&id,&username,&department,&createtime)
      fmt.Println(id,username,department,createtime)
   }
   //4、删除操作
   stmt3, _ := db.Prepare("delete from user_info where id=?")
   info, _ := stmt3.Exec(10)
   fmt.Println(info)
}

Go语言之聊天室

1、服务端代码
/**
 * Description: 聊天室服务端
 */

package main

import (
   "net"
   "fmt"
   "strings"
   "os"
   "log"
)

var onlineConns = make(map[string]net.Conn)
var messageQueue = make(chan string, 1000)
var quitChan = make(chan bool)
var logFile *os.File
var logger *log.Logger

func CheckError(err error)  {
   if err != nil {
      panic(err)
   }
}

const (
   LOG_DIRECTORY = "./test.log"
)

func main()  {
   logFile,err := os.OpenFile(LOG_DIRECTORY, os.O_RDWR | os.O_CREATE, 0)
   if err != nil {
      fmt.Println("log file has created")
      os.Exit(-1)
   }
   defer logFile.Close()

   logger = log.New(logFile, "\r\n", log.Ldate|log.Ltime|log.Llongfile)

   listen_socket, err := net.Listen("tcp","127.0.0.1:8080")
   CheckError(err)
   defer listen_socket.Close()

   fmt.Println("service is waiting...")

   logger.Println("I am writing the logs...")

   go consumerMessage()

   for {
      conn, err := listen_socket.Accept()
      CheckError(err)
      //将conn存储到onlineConns映射表
      addr := fmt.Sprintf("%s",conn.RemoteAddr())
      onlineConns[addr] = conn

      for ip := range onlineConns{
         fmt.Print(ip)
      }
      go ProcessInfo(conn)
   }
}

func consumerMessage()  {
   for {
      select {
      case message := <- messageQueue :
         //对消息进行解析
         doProcessMessage(message)
      case <- quitChan :
         break
      }
   }
}

func doProcessMessage(message string)  {
   contents := strings.Split(message,"#")
   if len(contents) > 1 {
      addr := contents[0]
      addr = strings.Trim(addr," ")
      sendMessage := strings.Join(contents[1:],"#")
      if conn, ok := onlineConns[addr]; ok {
         _, err := conn.Write([]byte(sendMessage))
         if err != nil {
            fmt.Println("online conns send failure")
         }
      }
   }else {
      contents := strings.Split(message,"*")
      if strings.ToUpper(contents[1]) == "LIST" {
         var ips string = ""
         for i := range onlineConns {
            ips = ips + "|" + i
         }
         if conn, ok := onlineConns[contents[0]]; ok {
            _, err := conn.Write([]byte(ips))
            if err != nil {
               fmt.Println("online conns send failure")
            }
         }
      }
   }
}

func ProcessInfo(conn net.Conn)  {
   buf := make([]byte, 1024)
   defer func(conn net.Conn) {
      addr := fmt.Sprintf("%s",conn.RemoteAddr())
      delete(onlineConns,addr)
      conn.Close()
      for i := range onlineConns{
         fmt.Println("now online conns:" + i)
      }
   }(conn)

   for {
      numofBytes, err := conn.Read(buf)
      if err != nil {
         break
      }
      if numofBytes != 0 {
         message := string(buf[:numofBytes])
         messageQueue <- message
         //remoteAddr := conn.RemoteAddr()
         //fmt.Println(remoteAddr)
         //fmt.Printf("Has received this message: %s\n", string(buf[:numofBytes]))
      }
   }
}
2、客户端代码
/**
 * Description: 聊天室客户端
 */

package main

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

func CheckError(err error)  {
   if err != nil {
      panic(err)
   }
}

func messageSend(conn net.Conn)  {
   var input string
   for {
      reader := bufio.NewReader(os.Stdin)
      data, _, _ := reader.ReadLine()
      input = string(data)

      if strings.ToUpper(input) == "EXIT" {
         conn.Close()
         break
      }

      _, err := conn.Write([]byte(input))
      if err != nil {
         conn.Close()
         fmt.Println("client connection failure:" + err.Error())
         break
      }
   }
}

func main()  {
   conn, err := net.Dial("tcp","127.0.0.1:8080")
   CheckError(err)
   defer conn.Close()

   //conn.Write([]byte("hell world"))
   go messageSend(conn)

   buf := make([]byte, 1024)
   for {
      length, err := conn.Read(buf)
      if err != nil {
         fmt.Println("您已经退出")
         os.Exit(0)
      }
      if length != 0 {
         fmt.Println("Has received server message:" + string(buf))
      }
   }
   fmt.Println("Client program end!")
}

变量逃逸-Escape Analysis

    go语言编译机制:自动决定变量分配方式,提高运行效率

    Go语言编程时,Go语言的设计者不希望开发者将精力放在内存应该分配在栈还是堆上的问题。编译器会自动帮助开发者完成这个纠结的选择。但变量逃逸分析也是需要了解的一个编译器技术。

    关于栈堆进行内存分配,Go语言将这个过程整合到编译器,命名为“变量逃逸分析”,这个技术由编译器分析代码的特征和代码生命期,决定应该如何堆还是栈进行内存分配,即使程序员使用Go完成了整个工程后也不会感受到这个过程

    1.逃逸分析

package main

import "fmt"

//逃逸分析
//变量c整形,值通过dummy()的返回值逃出函数
//c变量值被复制并作为函数dummy的返回值返回

func main()  {
   var a int
   void()
   fmt.Println(a,dummy(0))
}

func void()  {

}

func dummy(b int) int {
   var c int
   c = b
   return c
}

go run -gcflags "-m -l" escape1.go 
# command-line-arguments
./escape1.go:8:13: a escapes to heap
./escape1.go:8:21: dummy(0) escapes to heap
./escape1.go:8:13: main ... argument does not escape
0 0

    2、取地址发生逃逸

package main

import "fmt"

type Data struct {

}

func main()  {
   fmt.Println(dummys())
}

func dummys() *Data {
   var c  = Data{}
   return &c
}

go run -gcflags "-m -l" escape2.go 
# command-line-arguments
./escape2.go:15:9: &c escapes to heap
./escape2.go:14:6: moved to heap: c
./escape2.go:10:20: dummys() escapes to heap
./escape2.go:10:13: main ... argument does not escape
&{}

转载于:https://my.oschina.net/u/2555277/blog/2208528

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值