日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一口气说出 4种 “附近的人” 实现方式,面试官笑了

發布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一口气说出 4种 “附近的人” 实现方式,面试官笑了 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

昨天一位公眾號粉絲和我討論了一道面試題,個人覺得比較有意義,這里整理了一下分享給大家,愿小伙伴們面試路上少踩坑。面試題目比較簡單:“讓你實現一個附近的人功能,你有什么方案?”,這道題其實主要還是考察大家對于技術的廣度,本文介紹幾種方案,給大家一點思路,避免在面試過程中語塞而影響面試結果,如有不嚴謹之處,還望親人們溫柔指正!

“附近的人”?功能生活中是比較常用的,像外賣app附近的餐廳,共享單車app里附近的車輛。既然常用面試被問的概率就很大,所以下邊依次來分析基于mysql數據庫、Redis、?MongoDB實現的 “附近的人” 功能。

?

科普:世界上標識一個位置,通用的做法就使用經、緯度。經度的范圍在 (-180, 180],緯度的范圍 在(-90, 90],緯度正負以赤道為界,北正南負,經度正負以本初子午線 (英國格林尼治天文臺) 為界,東正西負。比如:望京摩托羅拉大廈的經、緯度(116.49141,40.01229)全是正數,就是因為我國位于東北半球。

一、“附近的人”原理

“附近的人”?也就是常說的?LBS?(Location Based Services,基于位置服務),它圍繞用戶當前地理位置數據而展開的服務,為用戶提供精準的增值服務。

“附近的人” 核心思想如下:

  • 以 “我” 為中心,搜索附近的用戶

  • 以 “我” 當前的地理位置為準,計算出別人和 “我” 之間的距離

  • 按 “我” 與別人距離的遠近排序,篩選出離我最近的用戶或者商店等

  • 二、什么是GeoHash算法?

    在說?“附近的人”?功能的具體實現之前,先來認識一下GeoHash?算法,因為后邊會一直和它打交道。定位一個位置最好的辦法就是用經、緯度標識,但經、緯度它是二維的,在進行位置計算的時候還是很麻煩,如果能通過某種方法將二維的經、緯度數據轉換成一維的數據,那么比較起來就要容易的多,因此GeoHash算法應運而生。

    GeoHash算法將二維的經、緯度轉換成一個字符串,例如:下圖中9個GeoHash字符串代表了9個區域,每一個字符串代表了一矩形區域。而這個矩形區域內其他的點(經、緯度)都用同一個GeoHash字符串表示。

    比如:WX4ER區域內的用戶搜索附近的餐廳數據,由于這區域內用戶的GeoHash字符串都是WX4ER,故可以把WX4ER當作key,餐廳信息作為value進行緩存;而如果不使用GeoHash算法,區域內的用戶請求餐廳數據,用戶傳來的經、緯度都是不同的,這樣緩存不僅麻煩且數據量巨大。

    GeoHash字符串越長,表示的位置越精確,字符串長度越長代表在距離上的誤差越小。下圖geohash碼精度表:

    geohash碼長度寬度高度
    15,009.4km4,992.6km
    21,252.3km624.1km
    3156.5km156km
    439.1km19.5km
    54.9km4.9km
    61.2km609.4m
    7152.9m152.4m
    838.2m19m
    94.8m4.8m
    101.2m59.5cm
    1114.9cm14.9cm
    123.7cm1.9cm

    而且字符串越相似表示距離越相近,字符串前綴匹配越多的距離越近。比如:下邊的經、緯度就代表了三家距離相近的餐廳。

    商戶經緯度Geohash字符串
    串串香116.402843,39.999375wx4er9v
    火鍋116.3967,39.99932wx4ertk
    烤肉116.40382,39.918118wx4erfe

    讓大家簡單了解什么是GeoHash算法,方便后邊內容展開,GeoHash算法內容比較高深,感興趣的小伙伴自行深耕一下,這里不占用過多篇幅(其實是我懂得太膚淺,哭唧唧~)。

    三、基于Mysql

    此種方式是純基于mysql實現的,未使用GeoHash算法。

    1、設計思路

    以用戶為中心,假設給定一個500米的距離作為半徑畫一個圓,這個圓型區域內的所有用戶就是符合用戶要求的 “附近的人”。但有一個問題是圓形有弧度啊,直接搜索圓形區域難度太大,根本無法用經、緯度直接搜索。

    但如果在圓形外套上一個正方形,通過獲取用戶經、緯度的最大最小值(經、緯度 + 距離),再根據最大最小值作為篩選條件,就很容易將正方形內的用戶信息搜索出來。

    那么問題又來了,多出來一些面積腫么辦?

    我們來分析一下,多出來的這部分區域內的用戶,到圓點的距離一定比圓的半徑要大,那么我們就計算用戶中心點與正方形內所有用戶的距離,篩選出所有距離小于等于半徑的用戶,圓形區域內的所用戶即符合要求的“附近的人”。

    2、利弊分析

    純基于?mysql?實現?“附近的人”,優點顯而易見就是簡單,只要建一張表存下用戶的經、緯度信息即可。缺點也很明顯,需要大量的計算兩個點之間的距離,非常影響性能。

    3、實現

    創建一個簡單的表用來存放用戶的經、緯度屬性。

    CREATE?TABLE?`nearby_user`?(`id`?int(11)?NOT?NULL?AUTO_INCREMENT,`name`?varchar(255)?DEFAULT?NULL?COMMENT?'名稱',`longitude`?double?DEFAULT?NULL?COMMENT?'經度',`latitude`?double?DEFAULT?NULL?COMMENT?'緯度',`create_time`?datetime?DEFAULT?NULL?ON?UPDATE?CURRENT_TIMESTAMP?COMMENT?'創建時間',PRIMARY?KEY?(`id`) )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8mb4;

    計算兩個點之間的距離,用了一個三方的類庫,畢竟自己造的輪子不是特別圓,還有可能是方的,啊哈哈哈~

    <dependency><groupId>com.spatial4j</groupId><artifactId>spatial4j</artifactId><version>0.5</version> </dependency>

    獲取到外接正方形后,以正方形的最大最小經、緯度值搜索正方形區域內的用戶,再剔除超過指定距離的用戶,就是最終的附近的人。

    ????private?SpatialContext?spatialContext?=?SpatialContext.GEO;????/***?獲取附近?x?米的人**?@param?distance?搜索距離范圍?單位km*?@param?userLng??當前用戶的經度*?@param?userLat??當前用戶的緯度*/@GetMapping("/nearby")public?String?nearBySearch(@RequestParam("distance")?double?distance,@RequestParam("userLng")?double?userLng,@RequestParam("userLat")?double?userLat)?{//1.獲取外接正方形Rectangle?rectangle?=?getRectangle(distance,?userLng,?userLat);//2.獲取位置在正方形內的所有用戶List<User>?users?=?userMapper.selectUser(rectangle.getMinX(),?rectangle.getMaxX(),?rectangle.getMinY(),?rectangle.getMaxY());//3.剔除半徑超過指定距離的多余用戶users?=?users.stream().filter(a?->?getDistance(a.getLongitude(),?a.getLatitude(),?userLng,?userLat)?<=?distance).collect(Collectors.toList());return?JSON.toJSONString(users);}private?Rectangle?getRectangle(double?distance,?double?userLng,?double?userLat)?{return?spatialContext.getDistCalc().calcBoxByDistFromPt(spatialContext.makePoint(userLng,?userLat),?distance?*?DistanceUtils.KM_TO_DEG,?spatialContext,?null);}

    由于用戶間距離的排序是在業務代碼中實現的,可以看到SQL語句也非常的簡單。

    ????<select?id="selectUser"?resultMap="BaseResultMap">SELECT?*?FROM?userWHERE?1=1and?(longitude?BETWEEN?${minlng}?AND?${maxlng})and?(latitude?BETWEEN?${minlat}?AND?${maxlat})</select>

    四、Mysql + GeoHash

    1、設計思路

    這種方式的設計思路更簡單,在存用戶位置信息時,根據用戶經、緯度屬性計算出相應的geohash字符串。注意:在計算geohash字符串時,需要指定geohash字符串的精度,也就是geohash字符串的長度,參考上邊的geohash精度表

    當需要獲取附近的人,只需用當前用戶geohash字符串,數據庫通過WHERE geohash Like 'geocode%' 來查詢geohash字符串相似的用戶,然后計算當前用戶與搜索出的用戶距離,篩選出所有距離小于等于指定距離(附近500米)的,即附近的人。

    2、利弊分析

    利用GeoHash算法實現“附近的人”有一個問題,由于geohash算法將地圖分為一個個矩形,對每個矩形進行編碼,得到geohash字符串。可我當前的點與鄰近的點很近,但恰好我們分別在兩個區域,明明就在眼前的點偏偏搜不到,實實在在的燈下黑。

    如何解決這一問題?

    為了避免類似鄰近兩點在不同區域內,我們就需要同時獲取當前點(WX4G0)所在區域附近?8個區域的geohash碼,一并進行篩選比較。

    3、實現

    同樣要設計一張表存用戶的經、緯度信息,但區別是要多一個geo_code字段,存放geohash字符串,此字段通過用戶經、緯度屬性計算出。使用頻繁的字段建議加上索引。

    CREATE?TABLE?`nearby_user_geohash`?(`id`?int(11)?NOT?NULL?AUTO_INCREMENT,`name`?varchar(255)?DEFAULT?NULL?COMMENT?'名稱',`longitude`?double?DEFAULT?NULL?COMMENT?'經度',`latitude`?double?DEFAULT?NULL?COMMENT?'緯度',`geo_code`?varchar(64)?DEFAULT?NULL?COMMENT?'經緯度所計算的geohash碼',`create_time`?datetime?DEFAULT?NULL?ON?UPDATE?CURRENT_TIMESTAMP?COMMENT?'創建時間',PRIMARY?KEY?(`id`),KEY?`index_geo_hash`?(`geo_code`) )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8mb4;

    首先根據用戶經、緯度信息,在指定精度后計算用戶坐標的geoHash碼,再獲取到用戶周邊8個方位的geoHash碼在數據庫中搜索用戶,最后過濾掉超出給定距離(500米內)的用戶。

    private?SpatialContext?spatialContext?=?SpatialContext.GEO;/****?添加用戶*?@return*/@PostMapping("/addUser")public?boolean?add(@RequestBody?UserGeohash?user)?{//默認精度12位String?geoHashCode?=?GeohashUtils.encodeLatLon(user.getLatitude(),user.getLongitude());return?userGeohashService.save(user.setGeoCode(geoHashCode).setCreateTime(LocalDateTime.now()));}/***?獲取附近指定范圍的人**?@param?distance?距離范圍(附近多遠的用戶)?單位km*?@param?len??????geoHash的精度(幾位的字符串)*?@param?userLng??當前用戶的經度*?@param?userLat??當前用戶的緯度*?@return?json*/@GetMapping("/nearby")public?String?nearBySearch(@RequestParam("distance")?double?distance,@RequestParam("len")?int?len,@RequestParam("userLng")?double?userLng,@RequestParam("userLat")?double?userLat)?{//1.根據要求的范圍,確定geoHash碼的精度,獲取到當前用戶坐標的geoHash碼GeoHash?geoHash?=?GeoHash.withCharacterPrecision(userLat,?userLng,?len);//2.獲取到用戶周邊8個方位的geoHash碼GeoHash[]?adjacent?=?geoHash.getAdjacent();QueryWrapper<UserGeohash>?queryWrapper?=?new?QueryWrapper<UserGeohash>().likeRight("geo_code",geoHash.toBase32());Stream.of(adjacent).forEach(a?->?queryWrapper.or().likeRight("geo_code",a.toBase32()));//3.匹配指定精度的geoHash碼List<UserGeohash>?users?=?userGeohashService.list(queryWrapper);//4.過濾超出距離的users?=?users.stream().filter(a?->getDistance(a.getLongitude(),a.getLatitude(),userLng,userLat)<=?distance).collect(Collectors.toList());return?JSON.toJSONString(users);}/****?球面中,兩點間的距離*?@param?longitude?經度1*?@param?latitude??緯度1*?@param?userLng???經度2*?@param?userLat???緯度2*?@return?返回距離,單位km*/private?double?getDistance(Double?longitude,?Double?latitude,?double?userLng,?double?userLat)?{return?spatialContext.calcDistance(spatialContext.makePoint(userLng,?userLat),spatialContext.makePoint(longitude,?latitude))?*?DistanceUtils.DEG_TO_KM;}

    五、Redis + GeoHash

    Redis 3.2版本以后,基于geohash和數據結構Zset提供了地理位置相關功能。通過上邊兩種mysql的實現方式發現,附近的人功能是明顯的讀多寫少場景,所以用redis性能更會有很大的提升。

    1、設計思路

    redis?實現附近的人功能主要通過Geo模塊的六個命令。

    • GEOADD:將給定的位置對象(緯度、經度、名字)添加到指定的key;

    • GEOPOS:從key里面返回所有給定位置對象的位置(經度和緯度);

    • GEODIST:返回兩個給定位置之間的距離;

    • GEOHASH:返回一個或多個位置對象的Geohash表示;

    • GEORADIUS:以給定的經緯度為中心,返回目標集合中與中心的距離不超過給定最大距離的所有位置對象;

    • GEORADIUSBYMEMBER:以給定的位置對象為中心,返回與其距離不超過給定最大距離的所有位置對象。

    以GEOADD?命令和GEORADIUS?命令簡單舉例:

    GEOADD?key?longitude?latitude?member?[longitude?latitude?member?...]

    其中,key為集合名稱,member為該經緯度所對應的對象。

    GEOADD?添加多個商戶“火鍋店”位置信息:

    GEOADD?hotel?119.98866180732716????30.27465803229662?火鍋店

    GEORADIUS?根據給定的經緯度為中心,獲取目標集合中與中心的距離不超過給定最大距離(500米內)的所有位置對象,也就是“附近的人”。

    GEORADIUS?key?longitude?latitude?radius?m|km|ft|mi?[WITHCOORD]?[WITHDIST]?[WITHHASH]?[ASC|DESC]?[COUNT?count]?[STORE?key]?[STORedisT?key]

    范圍單位:m?|?km?|?ft?|?mi?--> 米 | 千米 | 英尺 | 英里。

    • WITHDIST:在返回位置對象的同時,將位置對象與中心之間的距離也一并返回。距離的單位和用戶給定的范圍單位保持一致。

    • WITHCOORD:將位置對象的經度和維度也一并返回。

    • WITHHASH:以 52 位有符號整數的形式,返回位置對象經過原始 geohash 編碼的有序集合分值。這個選項主要用于底層應用或者調試,實際中的作用并不大。

    • ASC | DESC:從近到遠返回位置對象元素 | 從遠到近返回位置對象元素。

    • COUNT count:選取前N個匹配位置對象元素。(不設置則返回所有元素)

    • STORE key:將返回結果的地理位置信息保存到指定key。

    • STORedisT key:將返回結果離中心點的距離保存到指定key。

    例如下邊命令:獲取當前位置周邊500米內的所有飯店。

    GEORADIUS?hotel?119.98866180732716????30.27465803229662?500?m?WITHCOORD

    Redis內部使用有序集合(zset)保存用戶的位置信息,zset中每個元素都是一個帶位置的對象,元素的score值為通過經、緯度計算出的52位geohash值。

    2、利弊分析

    redis實現附近的人效率比較高,集成也比較簡單,而且還支持對距離排序。不過,結果存在一定的誤差,要想讓結果更加精確,還需要手動將用戶中心位置與其他用戶位置計算距離后,再一次進行篩選。

    3、實現

    以下就是Java?redis實現版本,代碼非常的簡潔。

    @Autowiredprivate?RedisTemplate<String,?Object>?redisTemplate;//GEO相關命令用到的KEYprivate?final?static?String?KEY?=?"user_info";public?boolean?save(User?user)?{Long?flag?=?redisTemplate.opsForGeo().add(KEY,?new?RedisGeoCommands.GeoLocation<>(user.getName(),?new?Point(user.getLongitude(),?user.getLatitude())));return?flag?!=?null?&&?flag?>?0;}/***?根據當前位置獲取附近指定范圍內的用戶*?@param?distance?指定范圍?單位km?,可根據{@link?org.springframework.data.geo.Metrics}?進行設置*?@param?userLng?用戶經度*?@param?userLat?用戶緯度*?@return*/public?String?nearBySearch(double?distance,?double?userLng,?double?userLat)?{List<User>?users?=?new?ArrayList<>();//?1.GEORADIUS獲取附近范圍內的信息GeoResults<RedisGeoCommands.GeoLocation<Object>>?reslut?=?redisTemplate.opsForGeo().radius(KEY,?new?Circle(new?Point(userLng,?userLat),?new?Distance(distance,?Metrics.KILOMETERS)),RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending());//2.收集信息,存入listList<GeoResult<RedisGeoCommands.GeoLocation<Object>>>?content?=?reslut.getContent();//3.過濾掉超過距離的數據content.forEach(a->?users.add(new?User().setDistance(a.getDistance().getValue()).setLatitude(a.getContent().getPoint().getX()).setLongitude(a.getContent().getPoint().getY())));return?JSON.toJSONString(users);}

    六、MongoDB + 2d索引

    1、設計思路

    MongoDB實現附近的人,主要是通過它的兩種地理空間索引?2dsphere?和?2d。兩種索引的底層依然是基于Geohash來進行構建的。但與國際通用的Geohash還有一些不同,具體參考官方文檔。

    2dsphere?索引僅支持球形表面的幾何形狀查詢。

    2d?索引支持平面幾何形狀和一些球形查詢。雖然2d?索引支持某些球形查詢,但?2d?索引對這些球形查詢時,可能會出錯。所以球形查詢盡量選擇?2dsphere索引。

    盡管兩種索引的方式不同,但只要坐標跨度不太大,這兩個索引計算出的距離相差幾乎可以忽略不計。

    2、實現

    首先插入一批位置數據到MongoDB,?collection為起名?hotel,相當于MySQL的表名。兩個字段name名稱,location?為經、緯度數據對。

    db.hotel.insertMany([{'name':'hotel1',??location:[115.993121,28.676436]},{'name':'hotel2',??location:[116.000093,28.679402]},{'name':'hotel3',??location:[115.999967,28.679743]},{'name':'hotel4',??location:[115.995593,28.681632]},{'name':'hotel5',??location:[115.975543,28.679509]},{'name':'hotel6',??location:[115.968428,28.669368]},{'name':'hotel7',??location:[116.035262,28.677037]},{'name':'hotel8',??location:[116.024770,28.68667]},{'name':'hotel9',??location:[116.002384,28.683865]},{'name':'hotel10',?location:[116.000821,28.68129]}, ])

    接下來我們給?location?字段創建一個2d索引,索引的精度通過bits來指定,bits越大,索引的精度就越高。

    db.coll.createIndex({'location':"2d"},?{"bits":11111})

    用geoNear命令測試一下,?near?當前坐標(經、緯度),spherical?是否計算球面距離,distanceMultiplier地球半徑,單位是米,默認6378137,?maxDistance?過濾條件(指定距離內的用戶),開啟弧度需除distanceMultiplier,distanceField?計算出的兩點間距離,字段別名(隨意取名)。

    db.hotel.aggregate({$geoNear:{near:?[115.999567,28.681813],?//?當前坐標spherical:?true,?//?計算球面距離distanceMultiplier:?6378137,?//?地球半徑,單位是米,那么的除的記錄也是米maxDistance:?2000/6378137,?//?過濾條件2000米內,需要弧度distanceField:?"distance"?//?距離字段別名} })

    看到結果中有符合條件的數據,還多出一個字段distance?剛才設置的別名,代表兩點間的距離。

    {?"_id"?:?ObjectId("5e96a5c91b8d4ce765381e58"),?"name"?:?"hotel10",?"location"?:?[?116.000821,?28.68129?],?"distance"?:?135.60095397487655?} {?"_id"?:?ObjectId("5e96a5c91b8d4ce765381e51"),?"name"?:?"hotel3",?"location"?:?[?115.999967,?28.679743?],?"distance"?:?233.71915803517447?} {?"_id"?:?ObjectId("5e96a5c91b8d4ce765381e50"),?"name"?:?"hotel2",?"location"?:?[?116.00009,?28.679402?],?"distance"?:?273.26317035334176?} {?"_id"?:?ObjectId("5e96a5c91b8d4ce765381e57"),?"name"?:?"hotel9",?"location"?:?[?116.00238,?28.683865?],?"distance"?:?357.5791936927476?} {?"_id"?:?ObjectId("5e96a5c91b8d4ce765381e52"),?"name"?:?"hotel4",?"location"?:?[?115.995593,?28.681632?],?"distance"?:?388.62555058249967?} {?"_id"?:?ObjectId("5e96a5c91b8d4ce765381e4f"),?"name"?:?"hotel1",?"location"?:?[?115.993121,?28.676436?],?"distance"?:?868.6740526419927?}

    總結

    本文重點并不是在具體實現,旨在給大家提供一些設計思路,面試中可能你對某一項技術了解的并不深入,但如果你的知識面寬,可以從多方面說出多種設計的思路,能夠侃侃而談,那么會給面試官極大的好感度,拿到offer的概率就會高很多。而且“附近的人”?功能使用的場景比較多,尤其是像電商平臺應用更為廣泛,所以想要進大廠的同學,這類的知識點還是應該有所了解的。

    總結

    以上是生活随笔為你收集整理的一口气说出 4种 “附近的人” 实现方式,面试官笑了的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产一区二区三区色淫影院 | 国产伦精品一区 | 日本一二三区在线 | 2022精品国偷自产免费观看 | 欧美人妖69xxxxxhd3d | 午夜免费看视频 | av激情在线| 亚洲乱码国产乱码精品精的特点 | 人妻少妇被猛烈进入中文字幕 | chinese hd av | 中国女人内96xxxxx | 成人免费大片黄在线播放 | 久久久精品网站 | 久久一区欧美 | 激情亚洲视频 | 偷拍精品一区二区三区 | 国产无套粉嫩白浆内谢 | 91丨九色丨蝌蚪丨丝袜 | 中文字幕在线视频不卡 | 成人91网站 | 国内毛片毛片毛片毛片 | 婷婷午夜精品久久久久久性色av | 四虎色网 | 蜜桃精品一区二区 | 欧美人与禽性xxxxx杂性 | 本田岬av| 国产96视频 | 成人网站免费观看入口 | 色视频2| japanese国产打屁股网站 | 超碰人人做 | 污片视频在线观看 | 日韩狠狠 | 成年人视频免费看 | 成年人的天堂 | 欧美在线导航 | 亚洲视频免费在线播放 | 九九精品在线视频 | 黄色av一区二区三区 | 在线观看av中文字幕 | 日韩在线视频中文字幕 | 亚洲欧美自拍一区 | 九色网站在线观看 | 欧美一级视频免费 | 三级不卡 | 亚洲久久久 | 亚洲午夜精品一区 | 伊人网综合 | 中文字幕在线视频网站 | 色婷婷综合久久久中文字幕 | 亚洲精品久久夜色撩人男男小说 | 国产伦精品一区二区三区 | av电影免费在线播放 | 国产婷| 懂色av蜜臀av粉嫩av分享吧最新章节 | 99国产精品久久久久99打野战 | 高清不卡一区二区三区 | 午夜精品美女久久久久av福利 | 成人免费精品视频 | 99久久久无码国产精品 | 视频在线国产 | 性午夜 | 国产精品刘玥久久一区 | 91嫩草香蕉 | 国产精品夜夜夜爽张柏芝 | 播放毛片 | 亚洲欧美视频在线 | 在线免费观看黄 | 精品视频一区二区三区四区五区 | 日日摸夜夜添夜夜 | 国产传媒在线播放 | 超能一家人电影免费喜剧在线观看 | 一区二区三区四区视频 | 亚洲老女人 | 三级黄色免费 | 日本免费观看视频 | 女女av在线| 欧美午夜在线 | 久久视频免费 | 91jk制服白丝超短裙大长腿 | 日本精品久久久久久 | 一区二区三区在线视频免费观看 | 亚洲一区二区三区91 | 国产一级在线播放 | 在线免费av网 | 国产高清免费视频 | 欧美另类国产 | 在线免费黄色网 | 欧美人喂奶吃大乳 | 国产 中文 字幕 日韩 在线 | 国产香蕉97碰碰碰视频在线观看 | 91精彩视频| 91禁在线看| 亚洲一级一区 | 成年人免费大片 | 国产无遮挡呻吟娇喘视频 | 手机在线观看毛片 | 精品区一区二区 | 色婷婷18|