2018年9月27日 星期四

MySQL Datetime and Timestemp

Basic


StackOverflow

Datetime 基本上就是儲存某個時間,通常不會改變。
Timestamp 基本上用來當作戳記,也就是會改變。當你改資料,會一起改timestamp。

Datetime

存入死的日期,就算更改mysql timezone,資料也不會變。

Timestamp

Save:current time zone converted to UTC for storage.
Retrieval: converted from UTC to current time zone for retrieval.
Timestamp存入的是UTC時間,取出後,會根據mysql time zone轉成當地時間。

兩者比較

處理速度大部份時候比datetime快。
timestamp有cache,datetime沒有。
timestamp有max 2038年問題。


Defult Value


官方說明

CREATE TABLE t1 (
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);


CREATE TABLE t1 (
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  dt DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE t1 (
  ts TIMESTAMP DEFAULT 0,
  dt DATETIME DEFAULT 0
);

CREATE TABLE t1 (
  ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
  dt DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE t1 (
  ts1 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,     -- default 0
  ts2 TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP -- default NULL
);

Eg.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

2018年9月24日 星期一

MySQL JOIN

INNER JOIN / JOIN

選取兩個表的交集部分,產生新的結果表。

Eg.

select item.id, item.weapon from item INNER join user on user.id=item.user_id;


LEFT OUTER JOIN

以左表為主,查詢左表中有,但右表中沒有的資料。


MySQL KEY, INDEX

KEY

Key 都會自動建立index
Key可以說是index加上某種限制

PRIMARY KEY

Only one PRIMARY KEY in a table
Value must be unique
Value can not be null
Indexing auto
Primary key允許欄位有null

UNIQUE KEY

Value of column must be unique
Can be null
Indexing auto
Unique key允許欄位有null

CREATE TABLE table_name(
	//...
   UNIQUE KEY(index_column_,index_column_2,...) 
);

//set unique index
CREATE UNIQUE INDEX index_name ON table_name(index_column_1,index_column_2,...);

FOREIGN KEY


Indexing auto
Only references to PRIMARY KEY in another table (NO)

Parameter:
ON DELETE {CASCADE | SET NULL | NO ACTION}
ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}

Eg.

CREATE TABLE item (
id INT AUTO_INCREMENT,
PRIMARY KEY(id),
user_id INT NOT NULL,
FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE ON UPDATE CASCADE);

條件

使用innodb

Eg.

CREATE TABLE product (
prod_id INT NOT NULL,
prod_name CHAR(20),
PRIMARY KEY (prod_id))
ENGINE = INNODB;

CREATE TABLE order (
order_id INT NOT NULL,
prod_id INT,
FOREIGN KEY(prod_id) REFERENCES product(prod_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
PRIMARY KEY (order_id))
ENGINE = INNODB;


設定 foreign key
 order table 的 prod_id 為foreign key

設定參數
ON DELETE CASCADE
ON UPDATE CASCADE

效果
此時如果 delete product table的某筆資料,
也會 delete order 有foreign key參考到的資料。

此時如果update product table的某筆 prod_id,
也會 update order 有foreign key參考到的 prod_id。

此時drop product table 會出錯,因為 order table 參考到它。

FOREIGN KEY 參數說明

[ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]

當關聯父資料表的主鍵紀錄行被刪除或修改時,InnoDB 對子資料表中紀錄行的處理方式:

CASCADE - 會將有所關聯的紀錄行也會進行刪除或修改。
SET NULL - 會將有所關聯的紀錄行設定成 NULL。
NO ACTION - 有存在的關聯紀錄行時,會禁止父資料表的刪除或修改動作。
RESTRICT - 與 NO ACTION 相同。

FOREIGN KEY效用

  1. 利用 db schema 防止程式錯誤及阻擋不合法寫入。
  2. 加速 join 效率。

INDEX

參考
Create a indexing data in another table for searching faster.
Index 允許欄位有null
Index 不必要是唯一值

Eg.
CREATE TABLE index_sample(
id INT,
index id_idx(id));

Eg.1
CREATE INDEX index_name ON table_name(column_name(length));

If column is CHAR, VARCHAR type, lenght can less then real length.
If is BLOB or TEXT ,must have length assigned.

Eg.2
ALTER table_name ADD INDEX index_name ON column_name(length))

組合索引

把常用的幾個一起查詢的欄位,建立成一個組合索引,效率更好。

CREATE TABLE my_table(  
id INT NOT NULL,   
user_name VARCHAR(16) NOT NULL,  
city VARCHAR(50) NOT NULL,  
age INT NOT NULL 
);  

//三個欄位建立組合索引
ALTER TABLE my_table ADD INDEX name_city_age (uer_name(10),city,age); 


等於建立以下三個索引
user_name, city, age
user_name, city
user_name
因為索引組合是從最左邊開始的。

以下查詢會用到這個組合索引

SELECT * FROM my_table WHERE user_name="name" AND city="zz"
SELECT * FROM my_table WHERE user_name="abc"
以下查詢不會用到這個組合索引

SELECT * FROM my_table WHERE age=10 AND city="zz"
SELECT * FROM my_table WHERE city="qqq"

INDEX使用時機

Mysql 在以下時機使用

//在 WHERE 中使用
//在 JOIN 中使用
< 
<=
=
>
>=
BETWEEN
IN
及某些LIKE
LIKE "%qee",用%開頭的LIKE不會用索引
LIKE "qee%"這樣會用

以下要對city 及 age建立索引,
my_table的user_name也要。

SELECT t.Name 
FROM my_table t LEFT JOIN my_table m   
ON t.Name=m.user_name WHERE m.age=20 AND m.city="xxx" 




索引的缺點

  • 索引加快搜尋速度,降低更改速度。因為INSERT, UPDATE, DELETE也要更新索引。
  • 索引會佔用一點空間。

使用索引注意事項,以下不會使用索引

  • 當mysql優化器判斷全表掃描比索引快
  • 索引不會包含有NULL的欄位
  • 多使用短索引
  • 不鼓勵使用LIKE
  • 不要在SQL語句上計算
  • 不要在SQL語句上使用函數運算
//這樣有計算
select * from users where YEAR(adddate)

//改成這樣
select * from users where adddate<‘2007-01-01’
  • 不使用NOT IN 和 <>
  • 類型錯誤
  • //假設 X type 是 char
    select * from users where X =1
    
    //改成這樣
    select * from users where X ='1'
    

強制使用索引

force index 索引名

優化

my.cnf 中的 key_buffer 值能夠把所有索引容納進去最好
SQL 指令前加上 explain 來顯示該 SQL 是否用到索引

2018年9月18日 星期二

MySQL 8.0 更改為native password 及 忘記密碼重設



更改為native password

[mysqld]
default-authentication-plugin=mysql_native_password

新的
default-authentication-plugin=caching_sha2_password

這樣子沒用,會造成原本的root無法登入。
mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'password';


移除password validate 


UNINSTALL COMPONENT 'file://component_validate_password';


重設密碼


Stop the MySQL server if necessary, then restart it with the --skip-grant-tables
shell> mysql
mysql> FLUSH PRIVILEGES;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';

2018年9月17日 星期一

Homebrew

Command

Package


Package installed Path

/user/local/Cellar/

List installed package

brew list

List target package

brew list mysql

Install package of latest version 

brew install mysql

Install package of target version

brew install mysql@5.6

Unlink now package

brew unlink mysql@5.6

Switch to new package

brew switch <formula><version>
brew switch mysql 8.0.12

Check current linked package

ls /usr/local/Cellar/<package>
ls /usr/local/Cellar/mysql

List which version of package is currently symlinked

ls -l /usr/local/bin/msyql  => ../Cellar/mysql56/5.6.27/bin/mysql

Service


Install brew services

brew tab homebrew/services

Start/stop a service

sudo brew services start mysql
sudo brew services stop mysql

is equal to:
* ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
* launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

List installed services

brew services list

Run but not a background service

mysql.server start

List services

brew services list

MySQL

homebrew github

裝多份mysql 出現 connect /tmp/mysql.sock  error

裝多個版本

Start mysql as service

sudo brew services start mysql
sudo brew services stop mysql

Run but not a background service


mysql.server start

重複裝 出現connect /tmp/mysql.sock error,

先把之前的data folder 刪掉,
unlink,移除再重裝(或 reinstall)


2018年9月10日 星期一

Goland mac delve problem

Debug時錯誤

Error:could not launch process: EOF
Reason:goland使用內建的dlv,版本太舊,改用新的就可以了。

1 brew安裝delve

https://github.com/go-delve/homebrew-delve

2 goland 指定使用自己安裝的delve

選單 Help / Edit custom properties...
dlv.path=/Users/cruise/go/bin/dlv

2018年8月5日 星期日

OOP的五個原則

1. S Single Responsibility Principle (SRP) 單一職責
2. O Open Closed Principle (OCP)           開放封閉
3. L Liskov’s Substitution Principle (LSP) 里氏替換原則
4. I Interface Segregation Principle (ISP) 介面隔離
5. D Dependency Inversion Principle (DIP)  依賴倒轉

各原則是相通且相輔相成的。(廢話,各原則當然不可能互相抵觸。)

某原則可能是其他原則的基礎。

因為注重『單一職責』,程式碼才容易維持『開放封閉』。

因為『里氏替換原則』,才能用替換子物件的方式擴充功能(開放封閉)。

因為『介面隔離』,每個物件遵循各自介面,才能『依賴倒轉』。

Single Responsibility Principle
單一職責原則 / 只能有單一原因去更改類別

  • There should never be more than one reason for a class to change.
  • 每個類別(或者模組)只能有一種原因去改變它。意即每個類別只負責一個職責。
原則很簡單,但是職責的劃分很難。

原文由Robert C. Martin在《敏捷軟體開發,原則,模式和實踐》一書提出。

Robert C. Martin把職責定義為「改變的原因」。職責從另一個角度,就是改變的原因。也許從這個角度看,比較容易劃分。

書中範例:
一個用於編輯和列印報表的類別,有兩種原因會改變它,一個是因為報表內容改變,一個是報表格式改變。這兩種原因有本質上的不同,

所以應區分為兩個類。否則會因為改動其中一個原因而影響另一個。

設計類別(模組)時,要思考,之後只能因為一種原因而改變這個類別的內容。
如果你只會因為一種原因改變它,那它自然就只有一種職責。
從這個角度去思考職責劃分,就比較容易了。

範例武器系統:
遊戲的武器系統模組有「強化」「進階」等功能。每個都應該是一個單一模組。
兩個功能對象都是武器,可能輸入的是相同資料。
如果企劃更改「強化」效果,就要改模組。但「強化」跟「進階」是各自獨立的,所以設計成單一模組。

Open Closed Principle
開放封閉原則

  • Software entities (classes, modules, functions) should be open for extension but closed for modification.
  • 軟體實體(包括類別,模組,函式等)應讓外部能擴展自己的功能,
但對外關閉修改功能。

外部透過繼承等方式,擴充某實體的功能。關鍵字是:擴展
外部不能修改它原本的功能。關鍵字是:修改

垂直擴展:
實作上使用介面的方式,定義出開放的部分。繼承者實作介面,然後加讓自己的功能,可達到垂直擴展。

橫向擴展:
新的實體實作相同的介面,裡面提供不同的功能,就能達到橫向擴展。

橫向擴展:
一個實體實作了兩組介面,就能成為兩組繼承鏈的橋樑,達到橫向擴展。

除開放的介面外,其餘一律不跟外界接觸,達到修改封閉。

Lislov's Substitution Principle
里氏替換原則

  • Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
  • 物件的父類可被其子類替換,而程式行為並無改變。
因為可替換,才延伸出可用子類擴充父類的功能。

因為雙方依賴於抽象層,於是可替換。

Interface Segregation Principle
介面隔離原則

  • Clients should not be forced to depend upon interfaces that they don't use.
  • The dependency of one class to another one should depend on the smallest possible interface。
  • 實作端不應被強迫依賴於它們用不到的介面上。
  • 一個類別依賴於另一個,最好只依賴於最少的介面上。
依賴於用不到的介面,就增加了耦合度,增加未來修改的負擔。總之就是依賴越小越好。

類別依賴於另一類別的介面上,也是越少越好,少到只要能滿組自己需求即可。

『單一職責』告訴我們未來修改的原因只能有一個,因此它不可能有太多功能,意即它只需依賴少少的介面。

介面設計時應區分出來,讓每個類別不碰到不需要的介面。

因為都依賴於抽象層,所以抽象層要劃分的小一點,否則就失去這些原則的功能了。

Dependency Inversion Principle
依賴倒轉原則


  • A high level module should not depend on low level modules. Both should depend on abstractions.
  • Abstractions should not depend on details. Details should depend on abstractions.
  • 高層模組不依賴於低層模組(例如某函式庫),兩者應透過抽象層溝通。例如兩者可透過中間定義的介面來溝通。
  • 抽象不依賴於細節(實作),細節依賴於抽象,其實跟上面同樣意思。兩者的原則都是要依賴於抽象(某介面)。

相互之間只依賴於介面,誰也不依賴另一方,雙方可以獨立修改,才能做到其他原則。

才能開放-封閉。各自內部修改,透過介面對外開放。子物件只要遵循相同介面,就能擴充功能。

中文翻譯的不好,讓人看不懂。個人的理解是透過抽象介面解除依賴,理解成『依賴解除』好點。

2018年7月26日 星期四

實作每秒千萬級別的訊息發送系統

場景

網路協議:       TCP/IP
網路程式介面: socket
CCU:            1000,000
每秒發送訊息次數: 10
總訊息傳送次數:    1000,000*10=10,000,000

瓶頸

linux內核
每秒送出的TCP/IP封包次數上限約 10,000,000/sec


要遍歷全部的連線,一個一個發送訊息,所以需要加鎖。
數量高達1000,000,所以這個過程很久,導致其他操作無法執行。
例如login,logout,都要等全部發送完解鎖後,才能執行。

頻寬
頻寬約需400MB-600MB之間。

解法

針對linux內核發送TCP/IP封包次數上限瓶頸
減少發送次數,一秒內的訊息,全部組合成一個訊息,統一發送。

針對鎖的瓶頸
把1000,000連線,分拆為多個集合,用併發的方式同步處理,
可有效減少上鎖時間。
鎖用讀寫鎖,不用互斥鎖。

針對頻寬瓶頸
訊息壓鎖。
換1GB網卡,加大頻寬。

單機架構



分散架構

2018年7月25日 星期三

MySQL 輸出結果到檔案


範例

select * from table_name
INTO OUTFILE '/directory/output.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'


以上執行select * from table_name 輸出到 '/directory/output.csv',
以逗號為欄位的分隔符號,然後每個欄位資料以雙引號刮起來,
每筆資料結尾以 '\n' 結束。

MySQL FOREIGN KEY

條件

使用innodb

範例

CREATE TABLE product (
prod_id INT NOT NULL,
prod_name CHAR(20),
PRIMARY KEY (prod_id))
ENGINE = INNODB;

CREATE TABLE order (
order_id INT NOT NULL,
prod_id INT,
FOREIGN KEY(prod_id) REFERENCES product(prod_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
PRIMARY KEY (order_id))
ENGINE = INNODB;


設定 foreign key
 order table 的 prod_id 為foreign key

設定參數
ON DELETE CASCADE
ON UPDATE CASCADE

效果
此時如果 delete product table的某筆資料,
也會 delete order 有foreign key參考到的資料。

此時如果update product table的某筆 prod_id,
也會 update order 有foreign key參考到的 prod_id。

此時drop product table 會出錯,因為 order table 參考到它。

Foreign Key 參數說明

[ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]

當關聯父資料表的主鍵紀錄行被刪除或修改時,InnoDB 對子資料表中紀錄行的處理方式:

CASCADE - 會將有所關聯的紀錄行也會進行刪除或修改。
SET NULL - 會將有所關聯的紀錄行設定成 NULL。
NO ACTION - 有存在的關聯紀錄行時,會禁止父資料表的刪除或修改動作。
RESTRICT - 與 NO ACTION 相同。

Foreign Key效用

  1. 利用 db schema 防止程式錯誤及阻擋不合法寫入。
  2. 加速 join 效率。


2018年7月10日 星期二

Golang Primary Data Type


18種基本type
8種複合type

go lang 只有傳值,沒有傳參考
slice,map,pointer,channel都是參考類型,底層都有一個對應的資料結構
當傳slice,map,pointer當參數,修改其內容,也會改到底層對應資料

map
value,ok:=map["key"]
value=value
if無此key-value pair,value ==map element type的零值
if ok==true   表示有此key-value pair
if ok==false  表示無此key-value pair


Data type零值
int=0
bool = false
string= ""
複合類型 =nil
map,slice=nil
function =nil

closure 閉包
保留某個變數,以後可以使用。
不需要每次都建立該變數。
http://openhome.cc/Gossip/JavaScript/Closure.html

方法
是某個附屬於自定義類型的函式
或是附屬於自定義類型對應的指標類型的函式


Interface
只要一個類型實現了該interface的所以方法,那就是實現了該 interface

網路 Layers

OSI 網路七層 TCP/IP網路四層

OSI(Open System Interconnection) 網路七層                TCP/IP四層


應用層Application Layer   應用層Application Layer
表現層Presentation Layer
會談層Session Layer

傳送層Transport Layer       傳送層Transport Layer

網路層Network Layer          網路層Internet Layer
資料鏈結層Data Link Layer  鏈結層Link Layer
實體層

各層協定

應用層Application Layer

應用程式之間實際溝通的協定,大部分傳輸層建立在TCP之上
HTTP/WebSocket/FTP/SMTP/POP3/SSH/NFS/DNS/DHCP/IMAP
telnet/

傳送層Transport Layer

實際資料傳輸的協定
TCP(Transmission Control Protocol)
HTTP/FTP/SMTP/SSH/telnet/WebSocket
TCP會把TCP 會在傳輸層對將上層送來的過大訊息分割成多個分段(TCP segments)

UDP(User Datagram Protocol)
DNS/DHCP/某些影音串流
UDP 訊息過大時(整體封包長度超過 MTU),
會由 host 或 router 在 IP 層對封包進行分割,
將一個 IP packet 分割成多個 IP fragments,
接收端的系統需要做 IP 封包的重組,將多個 fragments 重組合併為原本的 IP 封包,
同時也會增加封包遺失的機率。
只要其中一個 IP fragment 遺失了,
接收端就會無法順利重組 IP 封包,因而造成封包的遺失。
安全做法是封包大小不能超過MTU。

PPTP(翻牆)

網路層Internet Layer

定義實體介面卡的邏輯位置(IP),及定義資料封包如何繞送的規則。
IP
ICMP:基於IP之上
常用工具ping:向目標主機傳出一個ICMP echo@要求封包,並等待接收echo回應封包。
常用工具trace:

鏈結層Link Layer

網路實際硬體、各種線材、機器
LAN/WAN/ARP/RJ-45乙太網路線/光纖/VDSL

各層資料

應用層Application Layer

傳送層Transport Layer

資料進入傳送層,會包上傳送層表頭,此時稱為segment(資料段)

網路層Internet Layer

資料段進入網路層,包入表頭後稱為packet(封包)

鏈結層Link Layer

packet進入鏈結層處理之後,會將封包前後分別加入表頭以及表尾,整個稱之為訊框(frame)
鏈結層也是唯一的一層,同時在資料的前後加入資訊。

net package of Golang

net package是幫network I/O 提供一個可攜性的介面

包括 TCP/IP, UDP, domain name solution, Unix domain socket.

net package 支援的網路類型 network

基本四類 ip, tcp, udp, unix ,請見文件Dial 一節

"tcp",
"tcp4" (IPv4-only),
"tcp6" (IPv6-only)
"udp",
"udp4" (IPv4-only),
"udp6" (IPv6-only),
"ip", "ip4" (IPv4-only)
"ip6" (IPv6-only)
"unix"
"unixgram"
"unixpacket".

network又可分為兩類
無連接 ip, udp, unix(DGRAM),
建立連接 tcp, unix(STREAM),需要監聽,有listener。

無連接基礎interface是Conn
有連接基礎interface是PacketConn

network interface 三個主要組成

1. sever 負責listen,取得conn
2. client 負責連上server (dial),建立conn
3. conn  stream導向的連線(Conn is a generic stream-oriented network connection.)

整個核心就是對conn的操作

基本模型
1. listen(server side)取得listener, accept之後取得conn
2. dial(client side)取得conn
3. conn的操作

Dial / Listen func
func Dial(network, address string) (Conn, error)
func Listen(net, laddr string) (Listener, error)


Example:
Dial("tcp", "golang.org:http")
Dial("tcp", "192.0.2.1:http")
Dial("tcp", "198.51.100.1:80")
Dial("udp", "[2001:db8::1]:domain")
Dial("udp", "[fe80::1%lo0]:53")
Dial("tcp", ":80")


//client
conn, err := net.Dial("tcp", "golang.org:80")

if err != nil {
 // handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')


//server
ln, err := net.Listen("tcp", ":8080")
if err != nil {
 // handle error
}
for {
 conn, err := ln.Accept()
 if err != nil {
  // handle error
 }
 go handleConnection(conn)
}

Conn是各種conn的基礎interface,
Dial()會判斷網路類型,回傳對應的conn。
例如是TCP網路,回傳TCPConn。

可以用dial()取得conn或是用各自的dial取得各自的conn。

取得Conn
func Dial(network, address string)(Conn,error)
func DialTimeout(network, address string, timeout time.Duration)(Conn,error)
func FileConn(f *os.File)(c Conn, err error)
func Pipe()(Conn,Conn)

取得Listener
func FileListener(f *os.File)(ln Listener, err error)
func Listen(network, address string)(Listener, error)


type Conn interface {
  
     Read(b []byte) (n int, err error)

     Write(b []byte) (n int, err error)
  
     Close() error
  
     LocalAddr() Addr
 
     RemoteAddr() Addr
 
     SetDeadline(t time.Time) error
 
     SetReadDeadline(t time.Time) error
 
     SetWriteDeadline(t time.Time) error
 }

type PacketConn interface {
  
     ReadFrom(b []byte) (n int, addr Addr, err error)

     Close() error

     LocalAddr() Addr

     SetDeadline(t time.Time) error

     SetReadDeadline(t time.Time) error

     SetWriteDeadline(t time.Time) error
}

各種CONN


Conn
  a interface, generic stream-oriented network connection.
  Read()
  Write()
PacketConn
  a interface, generic packet-oriented network connection.
網路層的conn
  ReadFrom()
  WriteTo()

Conn跟PacketConn是兩種基礎interface,實際應用的四種Conn分別實作他們。

IPConn
  實作Conn及PacketConn的IP network connections.
  func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error)
  func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error)

TCPConn
  實作Conn的TCP network connections.
  func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error)
  func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error)

UDPConn
  實作Conn及PacketConn的UDP network connections.
  func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error)
  func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error)

UnixConn
  實作Conn及PacketConn的Unix socket connections.
  SOCK_DGRAM
  func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error)
  func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error)

  SOCK_STREAM
  func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error)
  func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error)

通用func


func ListenPacket(net, laddr string) (PacketConn, error)
監聽ip, udp, unix(DGRAM)等協議,返回packetConn。
packetConn可能是IPConn, UDPConn, UnixConn。

func Listen(net, laddr string) (Listener, error)
監聽tcp, unix(stream)等協議。返回Listener。
Listener有可能是TCPListener, UnixListener。

func Dial(network, address string) (Conn, error)
返回Conn。
依據network有可能是IPConn, UDPConn, TCPConn, UnixConn。

各network(IP/TCP/UDP/Unix)相關的物件


Conn
Addr
Listener

Example:
  IPConn
  IPAddr
  TCPAddr
  TCPConn
  TCPListener
  UDPAddr
  UDPConn
  UnixAddr
  UnixConn
  UnixListener

其他相關物件


Addr
Buffers
IP
IPNet
IPMask
MX
NS
Resolver  支援功能

支援功能


func LookupAddr(addr string) (names []string, err error)
func LookupCNAME(host string) (cname string, err error)
func LookupHost(host string) (addrs []string, err error)
func LookupIP(host string) ([]IP, error)
func LookupMX(name string) ([]*MX, error)
func LookupNS(name string) ([]*NS, error)
func LookupPort(network, service string) (port int, err error)
func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error)
func LookupTXT(name string) ([]string, error)

2018年7月9日 星期一

OOP in Golang

method繼承


在struct 中引入其他struct type,
就可以繼承他的method。


2018年7月7日 星期六

Golang Features


Collection

array

長度固定,元素相同。
實際上可以用interface當類型,所以可放不同類型元素。
array進行slice操作後,產生的是slice,非array。

declare array:

var grid [5][5]int
var buffer [20]byte
create array:

[3]string
[3]string{"a","b","c"}
[...]string{"a","b","c"}

grid[1][0],grid[1][1],grid[1][2]=8,6,3
grid2:=[3][3]int{{1,2,3},{1,2,3}}
cities:=[...]string{"a","b","c"}

slice

長度可變,元素相同。
slice底層是建立array,並引用它。 實際上可以用interface當類型,所以可放不同類型元素。
官方function都是使用slice。
同一個slice出來的slice,因為是引用相同array,
所以其中一個改變,會影響所有對該array的引用。


declare slice:

var grid [][]int

create slice:
不聲明數量,就是slice;聲明數量就是array。

[3]string
make([]Type,length,capacity)
make([]Type,length)
[]int{}
[]string{"a","b","c"}
s:=new([7]string)[:]   //new array然後slice全部,所以s是slice

s:=[]string{"a","b","c","d","e"}
t:=s[:5]
u:=s[3:len(s)-1]
u[1]="x"          //改變原本的array引用,所以影響所有slice


slice操作:

//尾部都不包括
s[n]    //slice n
s[n:m]  //slice n to m-1
s[n:]   //slice n to last
s[:m]   //slice 0 to m-1
s[:]    //slice all

內建函數

make

used to create slice,map,channel

len

append

cap

new

new struce,new array
new得到的是pointer

程式執行時的記憶體模型

程式運行時,作業系統會配置一塊記憶體給他使用。
這塊記憶體存放程式執行時的變數及各項資料。
這塊記憶的配置,是由程式所控制的。
記憶體的配置模型可分為三種,global、stack、heap。
程式執行時的記憶體需求,依據不同類型,配置在不同記憶體中。

其中heap是從該記憶體的最高位址開始配置。
stack是從最低位址開始配置。


global

程式中的全域變數或是static變數,配置在這個區域。
程式運行中,這些變數永遠存在,也就是記憶體都在使用,不會回收。

stack 堆疊/棧

生命週期可被預期的變數或是函數資料,配置在這個區域。
因為可以預期,所以這些記憶體可被系統自動管理,
不再使用時,系統自動回收。

常見的資料有:
區域變數
函數的參數
函數的返回地址

後進先出原則

等整個function執行結束,
整個stack都釋放了。

配置方式

stack使用是分次分配的,
每分配一個稱為一個frame。
從底位址往高位址一個一個分配,
後分配的(push )進去的會先釋放。
也就是後進先出。
取出稱為pop。
也因為後進先出、一層一層疊加的特性,
所以記憶體是從低位址開始使用,較為合理。

heap 堆

程式執行時才動態產生,
無法預期何時產生、數量多少、何時回收,
這些資料則配置在heap區域。
或是使用者要求,例如使用malloc函數。
這時記憶體就要由使用者自行回收,
或是由語言的Garbage Collection機制回收。

若回收不完全,就會產生out of memory的錯誤,
導致系統記憶體越用越少。

配置方式

每次配置一塊記憶體,每塊記憶體之間各自獨立。
從低位址往高位址配置
href="http://http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html">參考