国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

降低代碼的圈復(fù)雜度

開(kāi)發(fā) 前端

 0. 什么是圈復(fù)雜度

可能你之前沒(méi)有聽(tīng)說(shuō)過(guò)這個(gè)詞,也會(huì)好奇這是個(gè)什么東西是用來(lái)干嘛的,在維基百科上有這樣的解釋。

Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code. It was developed by Thomas J. McCabe, Sr. in 1976.

簡(jiǎn)單翻譯一下就是,圈復(fù)雜度是用來(lái)衡量代碼復(fù)雜程度的,圈復(fù)雜度的概念是由這哥們Thomas J. McCabe, Sr在1976年的時(shí)候提出的概念。

1. 為什么需要圈復(fù)雜度

如果你現(xiàn)在的項(xiàng)目,代碼的可讀性非常差,難以維護(hù),單個(gè)函數(shù)代碼特別的長(zhǎng),各種if else case嵌套,看著大段大段寫的糟糕的代碼無(wú)從下手,甚至到了根本看不懂的地步,那么你可以考慮使用圈復(fù)雜度來(lái)衡量自己項(xiàng)目中代碼的復(fù)雜性。

如果不刻意的加以控制,當(dāng)我們的項(xiàng)目達(dá)到了一定的規(guī)模之后,某些較為復(fù)雜的業(yè)務(wù)邏輯就會(huì)導(dǎo)致有些開(kāi)發(fā)寫出很復(fù)雜的代碼。

舉個(gè)真實(shí)的復(fù)雜業(yè)務(wù)的例子,如果你使用TDD(Test-Driven Development)的方式進(jìn)行開(kāi)發(fā)的話,當(dāng)你還沒(méi)有真正開(kāi)始寫某個(gè)接口的實(shí)現(xiàn)的時(shí)候,你寫的單測(cè)可能都已經(jīng)達(dá)到了好幾十個(gè)case,而真正的業(yè)務(wù)邏輯甚至還沒(méi)有開(kāi)始寫

再例如,一個(gè)函數(shù),有幾百、甚至上千行的代碼,除此之外各種if else while嵌套,就算是寫代碼的人,可能過(guò)幾周忘了上下文再來(lái)看這個(gè)代碼,可能也看不懂了,因?yàn)槠浯a的可讀性太差了,你讀懂都很困難,又談什么維護(hù)性和可擴(kuò)展性呢?

那我們?nèi)绾卧诰幋a中,CR(Code Review)中提早的避免這種情況呢?使用圈復(fù)雜度的檢測(cè)工具,檢測(cè)提交的代碼中的圈復(fù)雜度的情況,然后根據(jù)圈復(fù)雜度檢測(cè)情況進(jìn)行重構(gòu)。把過(guò)長(zhǎng)過(guò)于復(fù)雜的代碼拆成更小的、職責(zé)單一且清晰的函數(shù),或者是用設(shè)計(jì)模式來(lái)解決代碼中大量的if else的嵌套邏輯。

可能有的人會(huì)認(rèn)為,降低圈復(fù)雜度對(duì)我收益不怎么大,可能從短期上來(lái)看是這樣的,甚至你還會(huì)因?yàn)閯?dòng)了其他人的代碼,觸發(fā)了圈復(fù)雜度的檢測(cè),從而還需要去重構(gòu)別人寫的代碼。

但是從長(zhǎng)期看,低圈復(fù)雜度的代碼具有更佳的可讀性、擴(kuò)展性和可維護(hù)性。同時(shí)你的編碼能力隨著設(shè)計(jì)模式的實(shí)戰(zhàn)運(yùn)用也會(huì)得到相應(yīng)的提升。

2. 圈復(fù)雜度度量標(biāo)準(zhǔn)

那圈復(fù)雜度,是如何衡量代碼的復(fù)雜程度的?不是憑感覺(jué),而是有著自己的一套計(jì)算規(guī)則。有兩種計(jì)算方式,如下:

節(jié)點(diǎn)判定法

點(diǎn)邊計(jì)算法

判定標(biāo)準(zhǔn)我整理成了一張表格,僅供參考。

圈復(fù)雜度 說(shuō)明

1 - 10 代碼是OK的,質(zhì)量還行

11 - 15 代碼已經(jīng)較為復(fù)雜,但也還好,可以設(shè)法對(duì)某些點(diǎn)重構(gòu)一下

16 - ∞ 代碼已經(jīng)非常的復(fù)雜了,可維護(hù)性很低, 維護(hù)的成本也大,此時(shí)必須要進(jìn)行重構(gòu)

當(dāng)然,我個(gè)人認(rèn)為不能夠武斷的把這個(gè)圈復(fù)雜度的標(biāo)準(zhǔn)應(yīng)用于所有公司的所有情況,要按照自己的實(shí)際情況來(lái)分析。

這個(gè)完全是看自己的業(yè)務(wù)體量和實(shí)際情況來(lái)決定的。假設(shè)你的業(yè)務(wù)很簡(jiǎn)單,而且是個(gè)單體應(yīng)用,功能都是很簡(jiǎn)單的CRUD,那你的圈復(fù)雜度即使想上去也沒(méi)有那么容易。此時(shí)你就可以選擇把圈復(fù)雜度的重構(gòu)閾值設(shè)定為10.

而假設(shè)你的業(yè)務(wù)十分復(fù)雜,而且涉及到多個(gè)其他的微服務(wù)系統(tǒng)調(diào)用,再加上各種業(yè)務(wù)中的corner case的判斷,圈復(fù)雜度上100可能都不在話下。

而這樣的代碼,如果不進(jìn)行重構(gòu),后期隨著需求的增加,會(huì)越壘越多,越來(lái)越難以維護(hù)。

2.1 節(jié)點(diǎn)判定法

這里只介紹最簡(jiǎn)單的一種,節(jié)點(diǎn)判定法,因?yàn)榘ㄓ械墓ぞ咂鋵?shí)也是按照這個(gè)算法去算法的,其計(jì)算的公式如下。

圈復(fù)雜度 = 節(jié)點(diǎn)數(shù)量 + 1

節(jié)點(diǎn)數(shù)量代表什么呢?就是下面這些控制節(jié)點(diǎn)。

if、for、while、case、catch、與、非、布爾操作、三元運(yùn)算符

大白話來(lái)說(shuō),就是看到上面符號(hào),就把圈復(fù)雜度加1,那么我們來(lái)看一個(gè)例子。

圖片

我們按照上面的方法,可以得出節(jié)點(diǎn)數(shù)量是13,那么最終的圈復(fù)雜度就等于13 + 1 = 14,圈復(fù)雜度是14,值得注意的是,其中的&&也會(huì)被算作節(jié)點(diǎn)之一。

2.2 使用工具

對(duì)于golang我們可以使用gocognit來(lái)判定圈復(fù)雜度,你可以使用go get github.com/uudashr/gocognit/cmd/gocognit快速的安裝。然后使用gocognit $file就可以判斷了。我們可以新建文件test.go。

package main

import (

"flag"

"log"

"os"

"sort"

)

func main() {

log.SetFlags(0)

log.SetPrefix("cognitive: ")

flag.Usage = usage

flag.Parse()

args := flag.Args()

if len(args) == 0 {

usage()

}

stats := analyze(args)

sort.Sort(byComplexity(stats))

written := writeStats(os.Stdout, stats)

if *avg {

showAverage(stats)

}

if *over > 0 && written > 0 {

os.Exit(1)

}

}

然后使用命令gocognit test.go,來(lái)計(jì)算該代碼的圈復(fù)雜度。

$ gocognit test.go

6 main main test.go:11:1

表示main包的main方法從11行開(kāi)始,其計(jì)算出的圈復(fù)雜度是6。

3. 如何降低圈復(fù)雜度

這里其實(shí)有很多很多方法,然后各類方法也有很多專業(yè)的名字,但是對(duì)于初了解圈復(fù)雜度的人來(lái)說(shuō)可能不是那么好理解。所以我把如何降低圈復(fù)雜度的方法總結(jié)成了一句話那就是——“盡量減少節(jié)點(diǎn)判定法中節(jié)點(diǎn)的數(shù)量”。

換成大白話來(lái)說(shuō)就是,盡量少寫if、else、while、case這些流程控制語(yǔ)句。

其實(shí)你在降低你原本代碼的圈復(fù)雜度的時(shí)候,其實(shí)也算是一種重構(gòu)。對(duì)于大多數(shù)的業(yè)務(wù)代碼來(lái)說(shuō),代碼越少,對(duì)于后續(xù)維護(hù)閱讀代碼的人來(lái)說(shuō)就越容易理解。

簡(jiǎn)單總結(jié)下來(lái)就兩個(gè)方向,一個(gè)是拆分小函數(shù),另一個(gè)是想盡辦法少些流程控制語(yǔ)句。

3.1 拆分小函數(shù)

拆分小函數(shù),圈復(fù)雜度的計(jì)算范圍是在一個(gè)function內(nèi)的,將你的復(fù)雜的業(yè)務(wù)代碼拆分成一個(gè)一個(gè)的職責(zé)單一的小函數(shù),這樣后面閱讀的代碼的人就可以一眼就看懂你大概在干嘛,然后具體到每一個(gè)小函數(shù),由于它職責(zé)單一,而且代碼量少,你也很容易能夠看懂。除了能夠降低圈復(fù)雜度,拆分小函數(shù)也能夠提高代碼的可讀性和可維護(hù)性。

比如代碼中存在很多condition的判斷。

其實(shí)可以優(yōu)化成我們單獨(dú)拆分一個(gè)判斷函數(shù),只做condition判斷這一件事情。

圖片

3.2 少寫流程控制語(yǔ)句

這里舉個(gè)特別簡(jiǎn)單的例子。

圖片

其實(shí)可以直接優(yōu)化成下面這個(gè)樣子。

圖片

例子就先舉到這里,其實(shí)你也發(fā)現(xiàn),其實(shí)就像我上面說(shuō)的一樣,其目的就是為了減少if等流程控制語(yǔ)句。其實(shí)換個(gè)思路想,復(fù)雜的邏輯判斷肯定會(huì)增加我們閱讀代碼的理解成本,而且不便于后期的維護(hù)。所以,重構(gòu)的時(shí)候可以想辦法盡量去簡(jiǎn)化你的代碼。

那除了這些還有沒(méi)有什么更加直接一點(diǎn)的方法呢?例如從一開(kāi)始寫代碼的時(shí)候就盡量去避免這個(gè)問(wèn)題。

4. 使用go-linq

我們先不用急著去了解go-linq是什么,我們先來(lái)看一個(gè)經(jīng)典的業(yè)務(wù)場(chǎng)景問(wèn)題。

從一個(gè)對(duì)象列表中獲取一個(gè)ID列表

如果在go中,我們可以這么做。

圖片

略顯繁瑣,熟悉Java的同學(xué)可能會(huì)說(shuō),這么簡(jiǎn)單的功能為什么會(huì)寫的這么復(fù)雜,于是三下五除二寫下了如下的代碼。

圖片

上圖中使用了Java8的新特性Stream,而Go語(yǔ)言目前還無(wú)法達(dá)到這樣的效果。于是就該輪到go-linq出場(chǎng)了,使用go-linq之后的代碼就變成了如下的模樣。

圖片

怎么樣,是不是看到Java 8 Stream的影子,重構(gòu)之后的代碼我們暫且不去比較行數(shù),從語(yǔ)意上看,同樣的清晰直觀,這就是go-linq,我們用了一個(gè)例子來(lái)為大家介紹了它的定義,接下來(lái)簡(jiǎn)單介紹幾種常見(jiàn)的用法,這些都是官網(wǎng)上給的例子。

4.1 ForEach

與Java 8中的foreach是類似的,就是對(duì)集合的一個(gè)遍歷。

圖片

首先是一個(gè)From,這代表了輸入,夢(mèng)開(kāi)始的地方,可以和Java 8中的stream劃等號(hào)。

然后可以看到有ForEach和ForEachT,F(xiàn)orEachIndexed和ForEachIndexedT。前者是只遍歷元素,后者則將其下標(biāo)也一起打印了出來(lái)。跟Go中的Range是一樣的,跟Java 8的ForEach也類似,但是Java 8的ForEach沒(méi)有下標(biāo),之所以go-ling有,是因?yàn)樗约河涗浟艘粋€(gè)index,F(xiàn)orEachIndexed源碼如下。

圖片

其中兩者的區(qū)別是啥呢?我認(rèn)識(shí)是你對(duì)你要遍歷的元素的類型是否敏感,其實(shí)大多數(shù)情況應(yīng)該都是敏感的。如果你使用了帶T的,那么在遍歷的時(shí)候go-ling會(huì)將interface轉(zhuǎn)成你在函數(shù)中所定義的類型,例如fruit string。

否則的話,就需要我們自己去手動(dòng)的將interface轉(zhuǎn)換成對(duì)應(yīng)的類型,所以后續(xù)的所有的例子我都會(huì)直接使用ForEachT這種類型的函數(shù)。

4.2 Where

可以理解為SQL中的where條件,也可以理解為Java 8中的filter,按照某些條件對(duì)集合進(jìn)行過(guò)濾。

圖片

上面的Where篩選出了字符串長(zhǎng)度大于6的元素,可以看到其中有個(gè)ToSlice,就是將篩選后的結(jié)果輸出到指定的slice中。

4.3 Distinct

與你所了解到的MySQL中的Distinct,又或者是Java 8中的Distinct是一樣的作用,去重。

4.3.1 簡(jiǎn)單場(chǎng)景

4.3.2 復(fù)雜場(chǎng)景

當(dāng)然,實(shí)際的開(kāi)發(fā)中,這種只有一個(gè)整形數(shù)組的情況是很少的,大部分需要判斷的對(duì)象都是一個(gè)struct數(shù)組。所以我們?cè)賮?lái)看一個(gè)稍微復(fù)雜一點(diǎn)的例子。

圖片

上面的代碼是對(duì)一個(gè)products的slice,根據(jù)product的Code字段來(lái)進(jìn)行去重。

4.4 Except

對(duì)兩個(gè)集合做差集。

4.4.1 簡(jiǎn)單場(chǎng)景圖片

4.4.2 復(fù)雜場(chǎng)景圖片

4.5 Intersect

對(duì)兩個(gè)集合求交集。

4.5.1 簡(jiǎn)單場(chǎng)景圖片

4.5.2 復(fù)雜場(chǎng)景圖片

4.6 Select

從功能上來(lái)看,Select跟ForEach是差不多的,區(qū)別如下。

Select 返回了一個(gè)Query對(duì)象

ForEach 沒(méi)有返回值

在這里你不用去關(guān)心Query對(duì)象到底是什么,就跟Java8中的map、filter等等控制函數(shù)都會(huì)返回Stream一樣,通過(guò)返回Query,來(lái)達(dá)到代碼中流式編程的目的。

4.6.1 簡(jiǎn)單場(chǎng)景

圖片

select簡(jiǎn)單場(chǎng)景

其中SelectT就是遍歷了一個(gè)集合,然后做了一些運(yùn)算,將運(yùn)算之后的結(jié)果輸出到了新的slice中。

SelectMany為集合中的每一個(gè)元素都返回一個(gè)Query,跟Java 8中的flatMap類似,flatMap則是為每個(gè)元素創(chuàng)建一個(gè)Stream。簡(jiǎn)單來(lái)說(shuō)就是把一個(gè)二維數(shù)組給它拍平成一維數(shù)組。

4.6.2 復(fù)雜場(chǎng)景圖片

4.7 Group圖片

Group根據(jù)指定的元素對(duì)結(jié)合進(jìn)行分組,Group`的源碼如下。

圖片

Key就是我們分組的時(shí)候用key,Group就是分組之后得到的對(duì)應(yīng)key的元素列表。

好了,由于篇幅的原因,關(guān)于go-linq的使用就先介紹到這里,感興趣的可以去go-linq官網(wǎng)查看全部的用法。

5. 關(guān)于go-linq的使用

首先我認(rèn)為使用go-linq不僅僅是為了“逃脫”檢測(cè)工具對(duì)圈復(fù)雜度的檢查,而是真正的通過(guò)重構(gòu)自己的代碼,讓其變的可讀性更佳。

舉個(gè)例子,在某些復(fù)雜場(chǎng)景下,使用go-linq反而會(huì)讓你的代碼更加的難以理解。代碼是需要給你和后續(xù)維護(hù)的同學(xué)看的,不要盲目的去追求低圈復(fù)雜度的代碼,而瘋狂的使用go-linq。

我個(gè)人其實(shí)只傾向于使用go-linq對(duì)集合的一些操作,其他的復(fù)雜情況,好的代碼,加上適當(dāng)?shù)淖⑨?,才是不給其他人(包括你自己)挖坑的行為。而且并不是說(shuō)所有的if else都是爛代碼,如果必要的if else能夠大大增加代碼的可讀性,何樂(lè)而不為?(這里當(dāng)然說(shuō)的不是那種滿屏各種if else前套的代碼)

責(zé)任編輯:武曉燕
相關(guān)推薦

2022-08-16 09:04:23

代碼圈圈復(fù)雜度節(jié)點(diǎn)

2023-10-05 11:08:53

2023-03-03 08:43:08

代碼重構(gòu)系統(tǒng)

2024-07-30 10:55:25

2019-10-14 17:00:14

前端代碼圈復(fù)雜度

2020-06-01 08:42:11

JavaScript重構(gòu)函數(shù)

2024-06-05 09:35:00

2022-02-23 11:49:25

自動(dòng)化云基礎(chǔ)設(shè)施

2024-04-25 08:33:25

算法時(shí)間復(fù)雜度空間復(fù)雜度

2022-05-28 16:08:04

前端

2011-06-07 10:30:54

2015-10-13 09:43:43

復(fù)雜度核心

2021-01-05 10:41:42

算法時(shí)間空間

2009-07-09 10:45:16

C#基本概念復(fù)雜度遞歸與接口

2019-11-18 12:41:35

算法Python計(jì)算復(fù)雜性理論

2013-08-01 13:18:41

代碼

2021-10-15 09:43:12

希爾排序復(fù)雜度

2018-12-18 10:11:37

軟件復(fù)雜度軟件系統(tǒng)軟件開(kāi)發(fā)

2019-12-24 09:46:00

Linux設(shè)置密碼

2020-02-06 13:59:48

javascript算法復(fù)雜度
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

bestiality新另类大全| 午夜欧美精品| 极品粉嫩国产18尤物| 欧美午夜不卡影院在线观看完整版免费| 日本三级在线播放完整版| 欧美变态另类刺激| 欧美黑人性猛交| 在线āv视频| 国产一伦一伦一伦| 国产视频在线观看网站| 欧美极品一区| 欧美高清不卡在线| 欧美成人精品3d动漫h| 自拍偷在线精品自拍偷无码专区| 国产真实乱对白精彩久久| 自拍偷拍欧美专区| 韩国三级大全久久网站| 高潮一区二区| 亚洲电影欧美电影有声小说| 777久久久精品一区二区三区| 亚洲精品一区二区三区四区五区| 高清视频在线观看一区| 国产一区二区在线免费视频| 国产亚洲xxx| 日韩欧美在线网址| 亚洲女性喷水在线观看一区| 国产精品久久久久影院亚瑟| 午夜在线精品偷拍| 欧美三级午夜理伦三级中文幕| 国内亚洲精品| 色综合久久久| 久久亚洲资源中文字| 草民电影神马电影一区二区| 国产乱码在线| sqte在线播放| www在线观看播放免费视频日本| 99欧美精品| 欧美劲爆第一页| 精品国产拍在线观看| 欧美巨猛xxxx猛交黑人97人| 欧美性生交片4| 亚洲人妖av一区二区| 国产主播福利在线| 在线资源免费观看| 91中文字幕网| 天海翼一区二区三区免费| 天堂在线视频| 日本道免费精品一区二区三区| 欧美日韩免费一区| 亚洲成人av资源网| 欧美色18zzzzxxxxx| 老司机精品视频在线观看6| av女优在线| 男人操女人免费软件| 亚洲欧美日韩一区二区三区在线| 性做久久久久久免费观看欧美| 欧美日韩高清一区二区| 亚洲久久久久久久久久久| 91精品国产91久久久久久吃药| 久久久久久久一区二区三区| 亚洲一区二区三区中文字幕在线| 日韩欧美一区二区三区久久| 日韩成人在线电影网| 欧美激情在线观看视频| 91精品黄色| 成熟丰满熟妇高潮xxxxx视频| 国产又粗又长又爽视频| 理论片鲁丝二区爱情网| 欧美日韩色网| 日韩人体视频| 麻豆91在线播放免费| 亚洲自拍偷拍图区| 日韩中文在线视频| 青草青草久热精品视频在线网站| 性做久久久久久| 欧美日韩激情视频| 日韩一区二区免费在线观看| 欧美日韩麻豆| 久久这里只有精品18| 日本调教视频在线观看| 丰乳肥臀在线| 亚洲91视频| 国产色一区二区| 日韩中文字幕91| 四虎成人av| 国产精品美女久久久久高潮| 夜夜嗨av色综合久久久综合网| 国产伦精品一区二区三区| 欧美成人黄色网址| 伊人影院在线视频| 午夜精品婷婷| 色综合网色综合| 麻豆成人在线看| 激情五月六月婷婷| 成人爽a毛片免费啪啪动漫| 日韩视频在线一区二区三区 | 一区二区久久久| 97热在线精品视频在线观看| 欧美亚洲丝袜| 在线视频二区| 欧美区国产区| 香蕉乱码成人久久天堂爱免费| 久久99久久99精品中文字幕 | 99久久国产综合精品五月天喷水| 密臀av在线播放| 麻豆精品视频在线| 欧美日韩一区二区三区在线免费观看 | 日韩电影免费观看中文字幕| 蜜臀av一区二区| 国产欧美久久久精品影院| 国产亚洲人成网站在线观看| 亚洲一区二区三区精品视频| 天堂中文在线播放| 99久久综合精品| 欧美黑人视频一区| www.男人的天堂| 亚洲一区 二区 三区| 麻豆国产一区| 欧美一区二区三区免费看| 色88888久久久久久影院按摩| 亚州欧美日韩中文视频| 免费无码毛片一区二三区| 成人情趣视频网站| 激情五月激情综合网| 欧美一区二区三区在线观看视频 | 91精品免费看| 久久精品视频91| 国产欧美日韩视频在线| 欧美日韩国产专区| 一区二区三区四区国产| 丁香一区二区| 91麻豆精品国产自产在线 | 国产精品污www一区二区三区| 51精品视频| 亚洲欧美另类久久久精品2019| 国产精品麻豆免费版| 欧美男女交配| 亚洲va在线va天堂| 日本不卡一区二区三区四区| 精品国产一区探花在线观看 | 国产大尺度在线观看| 香蕉视频一区| 99欧美精品| 成人小视频免费在线观看| 国产99在线|中文| 国内在线免费视频| 国产乱国产乱300精品| 日韩亚洲国产中文字幕| 任你操这里只有精品| 亚洲日本成人| 日本国产欧美一区二区三区| 欧美成人a交片免费看| 樱桃视频在线观看一区| 欧美三级中文字幕在线观看| 一区二区三区国产豹纹内裤在线| 日韩在线精品视频| 久久视频免费在线| 欧美国产高清| 91精品成人久久| 播九公社成人综合网站| 午夜天堂精品久久久久| 欧美高清你懂得| 国产精品jizz在线观看老狼| 日韩免费电影在线观看| 午夜精品国产更新| 樱空桃在线播放| 三级欧美日韩| 亚洲天堂av图片| 色综合久久久久综合一本到桃花网| 久久久人人人| 欧洲亚洲国产日韩| 免费观看羞羞视频网站| 免费大片黄在线观看视频网站| 欧美在线三区| 97在线观看免费| 男人天堂亚洲| 亚洲综合在线五月| 手机看片一级片| 97精品久久久午夜一区二区三区| 尤物一区二区三区| 欧美国产91| 日韩av电影免费观看高清| 色av手机在线| 欧美一区二区三区视频免费| 三级黄色网址| 99久久99久久精品国产片果冻 | 日韩网站免费观看高清| 爱情电影网av一区二区 | 中文字幕日韩在线视频| 黄色大片在线播放| 欧美日韩一区三区四区| 一个人免费视频www在线观看| 久久av中文字幕片| 少妇高潮毛片色欲ava片| 日韩黄色免费电影| 男人插女人视频在线观看| 亚洲婷婷综合久久一本伊一区| 欧美12一14sex性hd| 在线观看av一区二区| 青青久草在线|