<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

    2017年8月3日 #

         摘要: 前陣子從支付寶轉(zhuǎn)賬1萬(wàn)塊錢(qián)到余額寶,這是日常生活的一件普通小事,但作為互聯(lián)網(wǎng)研發(fā)人員的職業(yè)病,我就思考支付寶扣除1萬(wàn)之后,如果系統(tǒng)掛掉怎么辦,這時(shí)余額寶賬戶(hù)并沒(méi)有增加1萬(wàn),數(shù)據(jù)就會(huì)出現(xiàn)不一致?tīng)顩r了。上述場(chǎng)景在各個(gè)類(lèi)型的系統(tǒng)中都能找到相似影子,比如在電商系統(tǒng)中,當(dāng)有用戶(hù)下單后,除了在訂單表插入一條記錄外,對(duì)應(yīng)商品表的這個(gè)商品數(shù)量必須減1吧,怎么保證?!在搜索廣告系統(tǒng)中,當(dāng)用戶(hù)點(diǎn)擊某廣告后,除了在點(diǎn)擊...  閱讀全文
    posted @ 2018-01-04 00:01 abin 閱讀(717) | 評(píng)論 (0)編輯 收藏

    微服務(wù)架構(gòu)采用Scale Cube方法設(shè)計(jì)應(yīng)用架構(gòu),將應(yīng)用服務(wù)按功能拆分成一組相互協(xié)作的服務(wù)。每個(gè)服務(wù)負(fù)責(zé)一組特定、相關(guān)的功能。每個(gè)服務(wù)可以有自己獨(dú)立的數(shù)據(jù)庫(kù),從而保證與其他服務(wù)解耦。
    微服務(wù)優(yōu)點(diǎn)
    1、通過(guò)分解巨大單體式應(yīng)用為多個(gè)服務(wù)方法解決了復(fù)雜性問(wèn)題,每個(gè)微服務(wù)相對(duì)較小
    2、每個(gè)單體應(yīng)用不局限于固定的技術(shù)棧,開(kāi)發(fā)者可以自由選擇開(kāi)發(fā)技術(shù),提供API服務(wù)。
    3、每個(gè)微服務(wù)獨(dú)立的開(kāi)發(fā),部署
    4、單一職責(zé)功能,每個(gè)服務(wù)都很簡(jiǎn)單,只關(guān)注于一個(gè)業(yè)務(wù)功能
    5、易于規(guī)模化開(kāi)發(fā),多個(gè)開(kāi)發(fā)團(tuán)隊(duì)可以并行開(kāi)發(fā),每個(gè)團(tuán)隊(duì)負(fù)責(zé)一項(xiàng)服務(wù)
    6、改善故障隔離。一個(gè)服務(wù)宕機(jī)不會(huì)影響其他的服務(wù)
    微服務(wù)缺點(diǎn):
    1.開(kāi)發(fā)者需要應(yīng)對(duì)創(chuàng)建分布式系統(tǒng)所產(chǎn)生的額外的復(fù)雜因素
    l  目前的IDE主要面對(duì)的是單體工程程序,無(wú)法顯示支持分布式應(yīng)用的開(kāi)發(fā)
    l  測(cè)試工作更加困難
    l  需要采用服務(wù)間的通訊機(jī)制
    l  很難在不采用分布式事務(wù)的情況下跨服務(wù)實(shí)現(xiàn)功能
    l  跨服務(wù)實(shí)現(xiàn)要求功能要求團(tuán)隊(duì)之間的緊密協(xié)作
    2.部署復(fù)雜
    3.內(nèi)存占用量更高
    posted @ 2017-12-31 16:41 abin 閱讀(417) | 評(píng)論 (0)編輯 收藏

    JDK 的 HashMap 中使用了一個(gè) hash 方法來(lái)做 bit shifting,在注釋中說(shuō)明是為了防止一些實(shí)現(xiàn)比較差的hashCode() 方法,請(qǐng)問(wèn)原理是什么?JDK 的源碼參見(jiàn):GrepCode: java.util.HashMap (.java)
    /**
     * Applies a supplemental hash function to a given hashCode, which
     * defends against poor quality hash functions.  This is critical
     * because HashMap uses power-of-two length hash tables, that
     * otherwise encounter collisions for hashCodes that do not differ
     * in lower bits. Note: Null keys always map to hash 0, thus index 0.
     */
    static int hash(int h) {
        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
    PS:網(wǎng)上看見(jiàn)有人說(shuō)作者本人說(shuō)原理需要參見(jiàn)圣經(jīng)《計(jì)算機(jī)程序設(shè)計(jì)藝術(shù)》的 Vol.3 里頭的介紹,不過(guò)木有看過(guò)神書(shū),求達(dá)人介紹





    這段代碼叫“擾動(dòng)函數(shù)”。
    題主貼的是Java 7的HashMap的源碼,Java 8中這步已經(jīng)簡(jiǎn)化了,只做一次16位右位移異或混合,而不是四次,但原理是不變的。下面以Java 8的源碼為例解釋?zhuān)?br />
    //Java 8中的散列值優(yōu)化函數(shù)staticfinalinthash(Objectkey){inth;return(key==null)?0:(h=key.hashCode())^(h>>>16);//key.hashCode()為哈希算法,返回初始哈希值}
    大家都知道上面代碼里的key.hashCode()函數(shù)調(diào)用的是key鍵值類(lèi)型自帶的哈希函數(shù),返回int型散列值。理論上散列值是一個(gè)int型,如果直接拿散列值作為下標(biāo)訪問(wèn)HashMap主數(shù)組的話(huà),考慮到2進(jìn)制32位帶符號(hào)的int表值范圍從-2147483648到2147483648。前后加起來(lái)大概40億的映射空間。只要哈希函數(shù)映射得比較均勻松散,一般應(yīng)用是很難出現(xiàn)碰撞的。但問(wèn)題是一個(gè)40億長(zhǎng)度的數(shù)組,內(nèi)存是放不下的。你想,HashMap擴(kuò)容之前的數(shù)組初始大小才16。所以這個(gè)散列值是不能直接拿來(lái)用的。用之前還要先做對(duì)數(shù)組的長(zhǎng)度取模運(yùn)算,得到的余數(shù)才能用來(lái)訪問(wèn)數(shù)組下標(biāo)。源碼中模運(yùn)算是在這個(gè)indexFor( )函數(shù)里完成的。

    bucketIndex = indexFor(hash, table.length);indexFor的代碼也很簡(jiǎn)單,就是把散列值和數(shù)組長(zhǎng)度做一個(gè)"與"操作,

    static int indexFor(int h, int length) {        return h & (length-1);}順便說(shuō)一下,這也正好解釋了為什么HashMap的數(shù)組長(zhǎng)度要取2的整次冪。因?yàn)檫@樣(數(shù)組長(zhǎng)度-1)正好相當(dāng)于一個(gè)“低位掩碼”。“與”操作的結(jié)果就是散列值的高位全部歸零,只保留低位值,用來(lái)做數(shù)組下標(biāo)訪問(wèn)。以初始長(zhǎng)度16為例,16-1=15。2進(jìn)制表示是00000000 00000000 00001111。和某散列值做“與”操作如下,結(jié)果就是截取了最低的四位值。
    10100101 11000100 00100101& 00000000 00000000 00001111---------------------------------- 00000000 00000000 00000101    //高位全部歸零,只保留末四位
    但這時(shí)候問(wèn)題就來(lái)了,這樣就算我的散列值分布再松散,要是只取最后幾位的話(huà),碰撞也會(huì)很?chē)?yán)重。更要命的是如果散列本身做得不好,分布上成等差數(shù)列的漏洞,恰好使最后幾個(gè)低位呈現(xiàn)規(guī)律性重復(fù),就無(wú)比蛋疼。這時(shí)候“擾動(dòng)函數(shù)”的價(jià)值就體現(xiàn)出來(lái)了,說(shuō)到這里大家應(yīng)該猜出來(lái)了。看下面這個(gè)圖,


    右位移16位,正好是32bit的一半,自己的高半?yún)^(qū)和低半?yún)^(qū)做異或,就是為了混合原始哈希碼的高位和低位,以此來(lái)加大低位的隨機(jī)性。而且混合后的低位摻雜了高位的部分特征,這樣高位的信息也被變相保留下來(lái)。最后我們來(lái)看一下PeterLawley的一篇專(zhuān)欄文章《An introduction to optimising a hashing strategy》里的的一個(gè)實(shí)驗(yàn):他隨機(jī)選取了352個(gè)字符串,在他們散列值完全沒(méi)有沖突的前提下,對(duì)它們做低位掩碼,取數(shù)組下標(biāo)。


    結(jié)果顯示,當(dāng)HashMap數(shù)組長(zhǎng)度為512的時(shí)候,也就是用掩碼取低9位的時(shí)候,在沒(méi)有擾動(dòng)函數(shù)的情況下,發(fā)生了103次碰撞,接近30%。而在使用了擾動(dòng)函數(shù)之后只有92次碰撞。碰撞減少了將近10%。看來(lái)擾動(dòng)函數(shù)確實(shí)還是有功效的。但明顯Java 8覺(jué)得擾動(dòng)做一次就夠了,做4次的話(huà),多了可能邊際效用也不大,所謂為了效率考慮就改成一次了。
    ------------------------------------------------------








    https://www.zhihu.com/question/20733617



    posted @ 2017-12-24 22:38 abin 閱讀(444) | 評(píng)論 (0)編輯 收藏

    Go語(yǔ)言沒(méi)有沿襲傳統(tǒng)面向?qū)ο缶幊讨械闹T多概念,比如繼承、虛函數(shù)、構(gòu)造函數(shù)和析構(gòu)函數(shù)、隱藏的this指針等。

     

    方法

    Go 語(yǔ)言中同時(shí)有函數(shù)和方法。方法就是一個(gè)包含了接受者(receiver)的函數(shù),receiver可以是內(nèi)置類(lèi)型或者結(jié)構(gòu)體類(lèi)型的一個(gè)值或者是一個(gè)指針。所有給定類(lèi)型的方法屬于該類(lèi)型的方法集。

    如下面的這個(gè)例子,定義了一個(gè)新類(lèi)型Integer,它和int一樣,只是為它內(nèi)置的int類(lèi)型增加了個(gè)新方法Less()

    復(fù)制代碼
    type Integer int   func (a Integer) Less(b Integer) bool {     return a < b  }  func main() {     var a Integer = 1       if a.Less(2) {         fmt.Println("less then 2")     }    }
    復(fù)制代碼

    可以看出,Go語(yǔ)言在自定義類(lèi)型的對(duì)象中沒(méi)有C++/Java那種隱藏的this指針,而是在定義成員方法時(shí)顯式聲明了其所屬的對(duì)象。

     

    method的語(yǔ)法如下:

    func (r ReceiverType) funcName(parameters) (results)

    當(dāng)調(diào)用method時(shí),會(huì)將receiver作為函數(shù)的第一個(gè)參數(shù):

    funcName(r, parameters);

    所以,receiver是值類(lèi)型還是指針類(lèi)型要看method的作用。如果要修改對(duì)象的值,就需要傳遞對(duì)象的指針。

    指針作為Receiver會(huì)對(duì)實(shí)例對(duì)象的內(nèi)容發(fā)生操作,而普通類(lèi)型作為Receiver僅僅是以副本作為操作對(duì)象,并不對(duì)原實(shí)例對(duì)象發(fā)生操作。

    復(fù)制代碼
    func (a *Ingeger) Add(b Integer) {     *a += b }  func main() {     var a Integer = 1      a.Add(3)     fmt.Println("a =", a)     //  a = 4 }
    復(fù)制代碼

    如果Add方法不使用指針,則a返回的結(jié)果不變,這是因?yàn)镚o語(yǔ)言函數(shù)的參數(shù)也是基于值傳遞。

    注意:當(dāng)方法的接受者是指針時(shí),即使用值類(lèi)型調(diào)用那么方法內(nèi)部也是對(duì)指針的操作。

     

    之前說(shuō)過(guò),Go語(yǔ)言沒(méi)有構(gòu)造函數(shù)的概念,通常使用一個(gè)全局函數(shù)來(lái)完成。例如:

    復(fù)制代碼
    func NewRect(x, y, width, height float64) *Rect {     return &Rect{x, y, width, height} }     func main() {     rect1 := NewRect(1,2,10,20)     fmt.Println(rect1.width) }
    復(fù)制代碼

     

     


    匿名組合

    Go語(yǔ)言提供了繼承,但是采用了組合的語(yǔ)法,我們將其稱(chēng)為匿名組合,例如:

    復(fù)制代碼
    type Base struct {     name string }  func (base *Base) Set(myname string) {     base.name = myname }  func (base *Base) Get() string {     return base.name }  type Derived struct {     Base     age int  }  func (derived *Derived) Get() (nm string, ag int) {     return derived.name, derived.age }   func main() {     b := &Derived{}      b.Set("sina")     fmt.Println(b.Get()) }
    復(fù)制代碼

    例子中,在Base類(lèi)型定義了get()和set()兩個(gè)方法,而Derived類(lèi)型繼承了Base類(lèi),并改寫(xiě)了Get()方法,在Derived對(duì)象調(diào)用Set()方法,會(huì)加載基類(lèi)對(duì)應(yīng)的方法;而調(diào)用Get()方法時(shí),加載派生類(lèi)改寫(xiě)的方法。

     

    組合的類(lèi)型和被組合的類(lèi)型包含同名成員時(shí), 會(huì)不會(huì)有問(wèn)題呢?可以參考下面的例子:

    復(fù)制代碼
    type Base struct {     name string     age int }  func (base *Base) Set(myname string, myage int) {     base.name = myname     base.age = myage }  type Derived struct {     Base     name string }  func main() {     b := &Derived{}      b.Set("sina", 30)     fmt.Println("b.name =",b.name, "\tb.Base.name =", b.Base.name)     fmt.Println("b.age =",b.age, "\tb.Base.age =", b.Base.age) }
    復(fù)制代碼

     

     

     


    值語(yǔ)義和引用語(yǔ)義

    值語(yǔ)義和引用語(yǔ)義的差別在于賦值,比如

    b = a b.Modify()

    如果b的修改不會(huì)影響a的值,那么此類(lèi)型屬于值類(lèi)型;如果會(huì)影響a的值,那么此類(lèi)型是引用類(lèi)型。

    Go語(yǔ)言中的大多數(shù)類(lèi)型都基于值語(yǔ)義,包括:

    • 基本類(lèi)型,如byte、int、bool、float32、string等;
    • 復(fù)合類(lèi)型,如arry、struct、pointer等;

     

    C語(yǔ)言中的數(shù)組比較特別,通過(guò)函數(shù)傳遞一個(gè)數(shù)組的時(shí)候基于引用語(yǔ)義,但是在結(jié)構(gòu)體定義數(shù)組變量的時(shí)候基于值語(yǔ)義。而在Go語(yǔ)言中,數(shù)組和基本類(lèi)型沒(méi)有區(qū)別,是很純粹的值類(lèi)型,例如:

    var a = [3] int{1,2,3} var b = a b[1]++ fmt.Println(a, b)   // [1 2 3] [1 3 3]

    從結(jié)果看,b=a賦值語(yǔ)句是數(shù)組內(nèi)容的完整復(fù)制,要想表達(dá)引用,需要用指針:

    var a = [3] int{1,2,3} var b = &a    // 引用語(yǔ)義 b[1]++ fmt.Println(a, b)   // [1 3 3] [1 3 3]

     

     


    接口

    Interface 是一組抽象方法(未具體實(shí)現(xiàn)的方法/僅包含方法名參數(shù)返回值的方法)的集合,如果實(shí)現(xiàn)了 interface 中的所有方法,即該類(lèi)/對(duì)象就實(shí)現(xiàn)了該接口。

    Interface 的聲明格式:

    type interfaceName interface {       //方法列表   }  

    Interface 可以被任意對(duì)象實(shí)現(xiàn),一個(gè)類(lèi)型/對(duì)象也可以實(shí)現(xiàn)多個(gè) interface;
    interface的變量可以持有任意實(shí)現(xiàn)該interface類(lèi)型的對(duì)象。

     如下面的例子:

    復(fù)制代碼
    package main      import "fmt"      type Human struct {         name string         age int         phone string     }      type Student struct {         Human //匿名字段         school string         loan float32     }      type Employee struct {         Human //匿名字段         company string         money float32     }      //Human實(shí)現(xiàn)SayHi方法     func (h Human) SayHi() {         fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)     }      //Human實(shí)現(xiàn)Sing方法     func (h Human) Sing(lyrics string) {         fmt.Println("La la la la...", lyrics)     }      //Employee重載Human的SayHi方法     func (e Employee) SayHi() {         fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,             e.company, e.phone)         }      // Interface Men被Human,Student和Employee實(shí)現(xiàn)     // 因?yàn)檫@三個(gè)類(lèi)型都實(shí)現(xiàn)了這兩個(gè)方法     type Men interface {         SayHi()         Sing(lyrics string)     }      func main() {         mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}         paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}         sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}         tom := Employee{Human{"Tom", 37, "222-444-XXX"}, "Things Ltd.", 5000}          //定義Men類(lèi)型的變量i         var i Men          //i能存儲(chǔ)Student         i = mike             fmt.Println("This is Mike, a Student:")         i.SayHi()         i.Sing("November rain")          //i也能存儲(chǔ)Employee         i = tom         fmt.Println("This is tom, an Employee:")         i.SayHi()         i.Sing("Born to be wild")          //定義了slice Men         fmt.Println("Let's use a slice of Men and see what happens")         x := make([]Men, 3)         //這三個(gè)都是不同類(lèi)型的元素,但是他們實(shí)現(xiàn)了interface同一個(gè)接口         x[0], x[1], x[2] = paul, sam, mike          for _, value := range x{             value.SayHi()         }     }
    復(fù)制代碼

     

    空接口

    空interface(interface{})不包含任何的method,正因?yàn)槿绱耍?span style="background-color: #ffff00;">所有的類(lèi)型都實(shí)現(xiàn)了空interface。空interface對(duì)于描述起不到任何的作用(因?yàn)樗话魏蔚膍ethod),但是空interface在我們需要存儲(chǔ)任意類(lèi)型的數(shù)值的時(shí)候相當(dāng)有用,因?yàn)樗梢源鎯?chǔ)任意類(lèi)型的數(shù)值。它有點(diǎn)類(lèi)似于C語(yǔ)言的void*類(lèi)型。

    復(fù)制代碼
    // 定義a為空接口     var a interface{}     var i int = 5     s := "Hello world"     // a可以存儲(chǔ)任意類(lèi)型的數(shù)值     a = i     a = s
    復(fù)制代碼

     

    interface的變量里面可以存儲(chǔ)任意類(lèi)型的數(shù)值(該類(lèi)型實(shí)現(xiàn)了interface),那么我們?cè)趺捶聪蛑肋@個(gè)interface變量里面實(shí)際保存了的是哪個(gè)類(lèi)型的對(duì)象呢?目前常用的有兩種方法:switch測(cè)試、Comma-ok斷言。

     

    switch測(cè)試如下:

    復(fù)制代碼
    type Element interface{} type List [] Element  type Person struct {     name string     age int  }  //打印 func (p Person) String() string {     return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)" }  func main() {     list := make(List, 3)     list[0] = 1 //an int      list[1] = "Hello" //a string     list[2] = Person{"Dennis", 70}       for index, element := range list{         switch value := element.(type) {             case int:                 fmt.Printf("list[%d] is an int and its value is %d\n", index, value)             case string:                 fmt.Printf("list[%d] is a string and its value is %s\n", index, value)             case Person:                 fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)             default:                 fmt.Println("list[%d] is of a different type", index)         }        }    }
    復(fù)制代碼

     

    如果使用Comma-ok斷言的話(huà):

    復(fù)制代碼
    func main() {     list := make(List, 3)     list[0] = 1 // an int     list[1] = "Hello" // a string     list[2] = Person{"Dennis", 70}      for index, element := range list {         if value, ok := element.(int); ok {             fmt.Printf("list[%d] is an int and its value is %d\n", index, value)         } else if value, ok := element.(string); ok {             fmt.Printf("list[%d] is a string and its value is %s\n", index, value)         } else if value, ok := element.(Person); ok {             fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)         } else {             fmt.Printf("list[%d] is of a different type\n", index)         }     } }
    復(fù)制代碼

     

     

    嵌入接口

    正如struct類(lèi)型可以包含一個(gè)匿名字段,interface也可以嵌套另外一個(gè)接口。

    如果一個(gè)interface1作為interface2的一個(gè)嵌入字段,那么interface2隱式的包含了interface1里面的method。

     

     

    反射

    所謂反射(reflect)就是能檢查程序在運(yùn)行時(shí)的狀態(tài)。

    使用reflect一般分成三步,下面簡(jiǎn)要的講解一下:要去反射是一個(gè)類(lèi)型的值(這些值都實(shí)現(xiàn)了空interface),首先需要把它轉(zhuǎn)化成reflect對(duì)象(reflect.Type或者reflect.Value,根據(jù)不同的情況調(diào)用不同的函數(shù))。這兩種獲取方式如下:

     t := reflect.TypeOf(i)    //得到類(lèi)型的元數(shù)據(jù),通過(guò)t我們能獲取類(lèi)型定義里面的所有元素  v := reflect.ValueOf(i)   //得到實(shí)際的值,通過(guò)v我們獲取存儲(chǔ)在里面的值,還可以去改變值

     

    轉(zhuǎn)化為reflect對(duì)象之后我們就可以進(jìn)行一些操作了,也就是將reflect對(duì)象轉(zhuǎn)化成相應(yīng)的值,例如

    tag := t.Elem().Field(0).Tag  //獲取定義在struct里面的標(biāo)簽 name := v.Elem().Field(0).String()  //獲取存儲(chǔ)在第一個(gè)字段里面的值

     

    獲取反射值能返回相應(yīng)的類(lèi)型和數(shù)值

    var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println("type:", v.Type()) fmt.Println("kind is float64:", v.Kind() == reflect.Float64) fmt.Println("value:", v.Float())

     

    最后,反射的話(huà),那么反射的字段必須是可修改的,我們前面學(xué)習(xí)過(guò)傳值和傳引用,這個(gè)里面也是一樣的道理。反射的字段必須是可讀寫(xiě)的意思是,如果下面這樣寫(xiě),那么會(huì)發(fā)生錯(cuò)誤

    var x float64 = 3.4 v := reflect.ValueOf(x) v.SetFloat(7.1)

     

    如果要修改相應(yīng)的值,必須這樣寫(xiě)

    var x float64 = 3.4 p := reflect.ValueOf(&x) v := p.Elem() v.SetFloat(7.1)

    上面只是對(duì)反射的簡(jiǎn)單介紹,更深入的理解還需要自己在編程中不斷的實(shí)踐。

     

     

    參考文檔:

    http://se77en.cc/2014/05/05/methods-interfaces-and-embedded-types-in-golang/

    http://se77en.cc/2014/05/04/choose-whether-to-use-a-value-or-pointer-receiver-on-methods/

     http://www.cnblogs.com/chenny7/p/4497969.html





    posted @ 2017-08-03 11:34 abin 閱讀(443) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲日本在线免费观看| 中文字幕免费播放| 日本免费一区二区三区最新| 亚洲综合激情五月色一区| 久久精品无码一区二区三区免费 | 亚洲av无码不卡| 嫩草成人永久免费观看| 亚洲高清在线视频| 国产成人精品久久免费动漫| 亚洲人成免费网站| vvvv99日韩精品亚洲| 最近的中文字幕大全免费8| 亚洲va中文字幕| 久久精品夜色国产亚洲av| 午夜爱爱免费视频| 2021在线永久免费视频| 羞羞视频在线免费观看| 日本久久久久亚洲中字幕| 免费a级毛片视频| 欧洲精品成人免费视频在线观看| sss在线观看免费高清| 一本天堂ⅴ无码亚洲道久久| 亚洲国产第一站精品蜜芽| 免费在线观看一级毛片| 精品久久8x国产免费观看| 好猛好深好爽好硬免费视频| 亚洲精品第一综合99久久| 亚洲国产成人久久精品动漫| 日本特黄a级高清免费大片| 精品一区二区三区免费毛片爱 | 国产v精品成人免费视频400条| 国产亚洲精品成人久久网站| 亚洲免费二区三区| 亚洲欧洲无码AV电影在线观看 | 亚洲hairy多毛pics大全| 亚洲成人激情在线| 亚洲乳大丰满中文字幕| 中文字幕中韩乱码亚洲大片| 亚洲v国产v天堂a无码久久| 国产免费av片在线无码免费看| 国产麻豆剧传媒精品国产免费|