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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java知识积累-基础篇

發布時間:2025/3/15 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java知识积累-基础篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

把前段時間看過的內容,結合面試經歷,作以整理,持續改進:D

Java基礎

JVM

emmmm,為什么把JVM放第一個咧……

主要是因為之前某次面試的時候被問到“從宏觀角度怎么看Java”才發現用了N年的Java竟然都沒好好看過這個

回想一下也是這感覺,從大二學Java以來一直沒把JVM當回事,回過來看才發現錯過了一個億orz

Java跨平臺的特性,主要歸功于Java虛擬機JVM——Java virtual machine

如圖,通過編譯.java源碼文件獲得.class字節碼文件,然后JVM通過類加載器加載字節碼文件,在虛擬機中運行

運行時的數據區主要有兩塊:線程共享區和獨占區/非共享區

例如一塊psvm里面Idea黨運行的代碼:

String s = new String("123"); 復制代碼

將它拆分為數個部分并對照上圖可得:

  • String s = xxxx → 對象s是保存字符串的引用的本地變量 → 本地方法棧Stack(獨占區)
  • new String(xxxx) → 通過帶參數的構造器實例化String對象并返回其引用 → 堆內存Heap(共享區)
  • "123" → 字符串常量 → 常量池 → 方法區Non-Heap(共享區)

這樣一解析,運行時數據存儲的區域就清晰很多了:D

Garbage Collection 垃圾回收

剛好前面恒生群面的時候有同學被問到了,這里也趁這機會總結一下

3種垃圾回收算法

1. 標記-清除(Mark-Sweep) 算法

標記可回收的對象,然后進行清除。

如圖,清理了紅色標記的部分,清理結束后多出綠色部分可用。

存在問題:

  • 標記-清除過程的效率有限
  • 內存碎片化
  • 2. 復制(Copying) 算法

    預留同樣大小的一塊內存,進行GC時復制存活的對象到復制用區并且順序放置(不留空隙)。

    優勢:避免碎片化問題;

    問題:復制需保留一塊內存,導致內存浪費

    3. 標記-整理(Mark-Compact) 算法

    類似于標記-清除,但是需對存活者進行整理

    優勢:避免碎片化問題

    基礎類型

    避免遺漏,通過類型區分,由小到大排序:

    • 整形
      • byte 字節 8-bit, -128~127
      • short 短整型 16-bit, -32,768~32,767
      • int 整形 32-bit
      • long 長整型 64-bit
    • 浮點
      • float 單精度浮點 32-bit
      • double 雙精度浮點 64-bit
    • 特殊
      • char 單字符 a single 16-bit Unicode character, 0~65,535
      • boolean 布爾值 represents 1 bit of information, but its "size" isn't something that's precisely defined.

    官方文檔《Oracle-Java教程-原始數據類型》

    包裝類型

    • 基礎類型都有對應的包裝類型(Integer、Char等

    • 在基礎類型和包裝類型之間通過自動裝箱拆箱完成賦值

      • Integer i = 3; 裝箱
      • int j = i; 拆箱
    • 默認值存在差異

      • 基礎類型默認值大都取0
      • 包裝類默認大都取null
    • 類型比較( ==和equals() )需注意

      • Integer var = ? 在[-128,127]范圍內的賦值,Integer 對象通過IntegerCache.cache產生,會復用已有對象,這個區間內的Integer 值可以直接使用==進行判斷,但是這個區間之外的所有數據,都會在堆上產生,并不會復用已有對象,推薦使用equals()進行比較
      基本類型==equals
      字符串變量對象在內存中的首地址字符串內容
      非字符串變量對象在內存中的首地址對象在內存中的首地址
      基本類型不可用
      包裝類地址內容

      表格參考自——alexyyek.github.io/2014/12/29/…

    字符串

    • String, StringBuffer, StringBuilder, StringJoiner

    • String 內容不可變(賦值改變的是引用)

      String s = "123"; //s只保存“123”的引用地址 s = "456"; // s保存了“456”的引用地址,"123"還鴿在內存里等回收 復制代碼
    • StringBuffer 線程安全Synchronized

    • StringBuilder 非線程安全

    • StringJoiner Java 1.8新寶貝,非線程安全(實際通過StringBuilder實現), [文檔]

      • 線程安全性:String > StringBuffer > StringBuilder ≈ StringJoiner
      • 內存消耗:String > StringBuffer > StringBuilder ≈ StringJoiner
      • 執行效率: String < StringBuffer < StringBuilder ≈ StringJoiner
    • 字符串拼接問題

      眾所周知String在循環里做拼接會耗時間耗內存,就想看看耗到什么程度

      代碼paste,若有問題歡迎指正qwq

      • 準備一個String的List,其他方法寫成靜態方法調用并返回String結果
      List<String> stringList = new ArrayList<>(); for (int i = 0; i < N; i++) {stringList.add(""+i); } for (int i = 1; i <= 5; i++) {runTestWithClock(i, stringList);// Thread.sleep(10000L); //用于查看內存時分隔每種方法 } 復制代碼
      • 準備一個計時器
      private static void runTestWithClock(int n, List<String> stringList){String result = null;long clock = System.currentTimeMillis(); // 記錄運行前時間long timer = 0;System.out.println("--------"+n+"-------");switch (n){case 1:result = sTest(stringList);break;case 2:result = sBufferTest(stringList);break;case 3:result = sBuilderTest(stringList);break;case 4:result = sJoiner(stringList);break;case 5:result = sjStreamTest(stringList);}timer = System.currentTimeMillis() - clock ; // 計算時間差System.out.println("Timer: "+timer);System.out.println(result); } 復制代碼
    • String +
    • String result = ""; for (String s: stringList){result = result + s + ","; } return result; // sTest:0,1,2,3,4,5,6,7,8,9,10,11,12...... 復制代碼
    • StringBuffer append()
    • StringBuffer sBuffer = new StringBuffer(); for (String s: stringList){sBuffer.append(s).append(","); } return sBuffer.toString(); // sBufferTest:0,1,2,3,4,5,6,7,8,9,10,11..... 復制代碼
    • StringBuilder append()
    • StringBuilder sBuilder = new StringBuilder(); for (String s: stringList){sBuilder.append(s).append(","); } return sBuilder.toString(); // sBuilderTest:0,1,2,3,4,5,6,7,8,9,10,11...... 復制代碼
    • StringJoiner add()
    • /* StringJoiner Since Java1.8 * @param:分隔符,前綴,后綴 * Docs: https://docs.oracle.com/javase/8/docs/api/java/util/StringJoiner.html */ StringJoiner sj = new StringJoiner(",", "[", "]"); for (String s: stringList){sj.add(s); } return sj.toString(); // sJoiner:[0,1,2,3,4,5,6,7,8,9,10,11......] 復制代碼
    • streamCollection.joining (stream特性詳見Java進階-語法糖-Streams API)
    • return stringList.stream().map(String::toString).collect(Collectors.joining(",", "[", "]")); // sjStreamTest:[0,1,2,3,4,5,6,7,8,9,10,11......] 復制代碼
      • 當N為100000時, 執行效率顯然String最慘
      --------1-------String Timer: 26841 --------2-------StringBuffer Timer: 14 --------3-------StringBuilder Timer: 11 --------4-------StringJoiner Timer: 10 --------5-------stream+joining Timer: 43 復制代碼
      • 正常狀態下的內存消耗曲線(Java VisualVM-監視-內存-堆)
      • 執行代碼時,出現了明顯增幅
      • 查看時間,均在使用String相加時發生,sleep10秒后執行其他方法沒有出現增幅明顯的跡象

    面向對象編程

    封裝

    public class User {private String userName;private String password;public User() {}public User(String userName, String password) {this.userName = userName;this.password = password;}public String getUserName() { return userName; }public void setUserName(String userName) { this.userName = userName; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; } } 復制代碼

    對象的屬性和方法封裝起來,不可直接暴露給外部訪問(例如對象實例user的password屬性不能用user.password直接獲取或修改),只能通過實例化對象的方法訪問內部屬性(user.getPassword())

    繼承

    public class VIP extends User{private int vipId;private int accessType;public VIP() {}public VIP(int vipId, int accessType) {// super(); // 隱藏this.vipId = vipId;this.accessType = accessType;}public VIP(String userName, String password, int vipId, int accessType) {super(userName, password);this.vipId = vipId;this.accessType = accessType;}// 省略getter, setter } 復制代碼

    VIP繼承自User,包含User所有屬性和方法,在此基礎上又擁有自己獨立的屬性和方法

    • 向上轉型

    User user = new VIP();

    有個疑問,使用List list = new ArrayList<>();算不算向上轉型,一方面ArrayList繼承自抽象類AbstractList,另一方面實現了List接口

    多態

    參考:www.runoob.com/java/java-p…

  • 重寫overwrite
  • class User {public void communicate(){ System.out.println("User is communicating."); } } class Teacher extends User{ //繼承自Userpublic void communicate(){ System.out.println("Teacher is communicating."); } //重寫超類的方法 } class Student extends User{ //繼承自Userpublic void communicate(){ System.out.println("Student is communicating."); } //重寫超類的方法 } public class Communication {public static void main(String[] args) {List<User> users = new ArrayList<>();users.add(new Teacher()); //向上轉型users.add(new Student()); //向上轉型for( User user: users ){user.communicate(); // 執行子類重寫的方法}} } // 繼承→重寫→向上轉型 復制代碼
    • 區別→重載overload
      • 重寫需要方法名、參數、返回值類型都相同
      • 重載需要方法名相同但是參數不同,返回值類型可以相同也可以不同
    public class Student{public Course searchCourse(int courseId){...}public Course searchCourse(String courseName){...}public List<Course> searchCourse(String instructorName, String courseType){...} } 復制代碼
  • 實現抽象類的抽象方法 User可改為抽象類,communicate()改成抽象方法
  • abstract class User {public abstract void communicate(); } class Teacher extends User{ //繼承自Userpublic void communicate(){ System.out.println("Teacher is communicating."); } //實現超類的抽象方法 } class Student extends User{ //繼承自Userpublic void communicate(){ System.out.println("Student is communicating."); } //實現超類的抽象方法 } public class Communication {public static void main(String[] args) {List<User> users = new ArrayList<>();users.add(new Teacher()); //向上轉型users.add(new Student()); //向上轉型for( User user: users ){user.communicate(); // 執行實現類實現的方法}} } // 繼承→實現→向上轉型 復制代碼
  • 接口
  • 這種實現方式在MVC里挺常用, 業務層Service和數據處理層Dao(或Repository)都會應用, 此處以Service為例,不同的實現使用的是不同的數據處理層

    public interface UserService { User findUserById(Integer userId); } public class UserServiceImplByRepository implements UserService {private UserRepository userRepository;@Overridepublic User findUserById(Integer userId) { return userRepository.findUserByUserId(userId); } } public class UserServiceImplByDao implements UserService {private UserDao userDao;@Overridepublic User findUserById(Integer userId) { return userDao.findUserByUserId(userId); } } public class UserController {public String user(int id){if( id < 1000 ){// 假設1000以下的使用Repository的實現UserService us = new UserServiceImplByRepository(); // UserService接口類型的變量引用指向UserServiceImpl實現類的對象return us.findUserById(id); // 此處使用的是UserServiceImplByRepository的方法}else{// 其他使用Dao的實現UserService us = new UserServiceImplByDao(); // UserService接口類型的變量引用指向UserServiceImplByDao實現類的對象return us.findUserById(id) ; // 此處使用的是UserServiceImplByDao的方法}} } 復制代碼

    反射

    一開始用JDBC的時候還不知道,回過頭來才發現早已在用了……

    寫完Class.forName("com.mysql.jdbc.Driver")就能用Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);來拿Connection連接

    可以看看JDBC例子回顧一下:D www.tutorialspoint.com/jdbc/jdbc-s…

    實際上手看看Class.forName和java.lang.reflect怎么用:

    public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {Class<?> userClass = Class.forName("cn.magiklau.java.basic.model.User");// 輸出Class名System.out.println("Class name: "+userClass.getName());Collector<CharSequence, ?, String> joining = Collectors.joining(", ", "[", "]"); // 方便格式化輸出System.out.print("DeclaredFields: ");// 使用getFields()只能取得public屬性,這里要取private屬性需要用getDeclaredFields()System.out.println(Arrays.stream(userClass.getDeclaredFields()).map(Field::getName).collect(joining));;System.out.print("DeclaredMethods: ");// 使用getMethods()也會取得超類的方法,這里還是只取本身的System.out.println(Arrays.stream(userClass.getDeclaredMethods()).map(Method::getName).collect(joining));// 取一個實例User user = (User)userClass.newInstance();user.setUserName("testUserName");System.out.println("Username: "+user.getUserName());} } 運行結果: Class name: cn.magiklau.java.basic.model.User DeclaredFields: [userName, password] DeclaredMethods: [getPassword, setUserName, getUserName, setPassword] Username: testUserName 復制代碼

    參考文章

    深入理解 Java 反射和動態代理 github.com/dunwu/blog/…

    深入解析Java反射(1) - 基礎 www.sczyh30.com/posts/Java/…

    類加載機制

    orz為了看反射竟然把類加載機制都看了一圈

    類加載的過程

    參考 網易云課堂-微專業-Java高級

  • 加載(Loading)

    讀取二進制內容

  • 驗證(Verification)

    驗證class文件格式規范、語義分析、引用驗證、字節碼驗證

  • 準備(Preparation)

    分配內存、設置類static修飾的變量初始值(此時除了final修飾以外的其他static變量均先給0或null值,只有final值是在此時確定的)

  • 解析(Resolution)

    類、接口、字段、類方法等解析

  • 初始化(Initialization)

    靜態變量賦值(對,static的值現在才給賦上),執行靜態代碼塊

  • 使用(Using)

    創建實例對象

  • 卸載(Unloading)

    從JVM方法區中卸載(條件:① 該Class所有實例都已經被GC;② 加載該類的ClassLoader實例已經被GC)

  • 雙親委派模型

    除了頂層ClassLoader以外,其他類加載器都需要有超類加載器,在超類加載失敗時才會交給子類加載

    // 竟然還不支持MarkDown畫圖……簡單記一下先 Bootstrap ClassLoader頂層啟動類加載器 ↑委托 ↓查找 Extension ClassLoader拓展類庫類加載器 ↑委托 ↓查找 Application ClassLoader 用戶應用程序類加載器 ↑委托 ↓查找 Custome ClassLoader 自定義類加載器 復制代碼

    又看到一些個神奇的做法,備用 www.cnblogs.com/chanshuyi/p…

    對象生命周期

    參考CSDN-Sodino-blog.csdn.net/sodino/arti…

  • 創建階段(Created)

  • 應用階段(In Use)

    對象至少被一個強引用持有

  • 不可見階段(Invisible)

    超出作用域

    for(int i = 0; i < 10; i++){ // in loop// i is visible }// out of the loop // i is invisible 復制代碼
  • 不可達階段(Unreachable)

    無任何強引用持有

  • 收集階段(Collected)

    gc已經對該對象的內存空間重新分配做好準備

  • 終結階段(Finalized)

    當對象執行完finalize()方法后仍然處于不可達狀態時,則該對象進入終結階段。在該階段是等待垃圾回收器對該對象空間進行回收

  • 對象空間重分配階段(De-allocated)

  • IO

    圖來自:runoob - Java 流(Stream)、文件(File)和IO - www.runoob.com/java/java-f…

    字節流 InputStream OutputStream

    // 讀操作 String filePath = "C:\\WorkSpace\\JavaProject\\JavaLearning\\src\\ioTestFile.txt"; // 字節流輸入,FileInputStream提供文件處理功能 InputStream fis = new FileInputStream(filePath); // BufferedInputStream提供緩存功能 InputStream bis = new BufferedInputStream(fis); while( bis.available() > 0 ){System.out.println((char) bis.read()); }// 同理進行寫操作 OutputStream fos = new FileOutputStream(filePath); OutputStream bos = new BufferedOutputStream(fos); bos.write("MagikIOTest~".getBytes()); bos.flush(); 復制代碼

    字符流 Reader Writer

    github.com/CyC2018/CS-…

    和流操作基本相似,也是在Reader里疊上File和Buffered裝飾

    FileReader fileReader = new FileReader(filePath); BufferedReader bufferedReader = new BufferedReader(fileReader);String gotLine; while ((gotLine = bufferedReader.readLine()) != null) {System.out.println(gotLine); }// 裝飾者模式使得 BufferedReader 組合了一個 Reader 對象 // 在調用 BufferedReader 的 close() 方法時會去調用 Reader 的 close() 方法 // 因此只要一個 close() 調用即可 bufferedReader.close();FileWriter fileWriter = new FileWriter(filePath); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write("MagikIOTest writer~"); bufferedWriter.close(); 復制代碼

    網絡 Socket

    Server: ServerSocket(port, timeout)

    Client: Socket(host, port)

    Server: accept()

    S/C: InputSteam->OutputSteam

    S/C: close()

    NIO

    非阻塞Non-Block IO

    參考 網易云課堂-微專業-Java高級

    三大核心組件:

    1. Buffer 緩沖區 2. Channel 通道 3. Selector 選擇器 復制代碼

    1. Buffer 緩沖區

    使用:

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(n); // 申請容量nbyteBuffer.put((byte) 1); // 寫 byteBuffer.flip(); // 轉換讀寫 byte b = byteBuffer.get(); // 讀byteBuffer.compact(); // 清除已閱讀的數據。轉為寫入模式 byteBuffer.clear(); // 清除整個緩沖區 復制代碼

    三屬性

  • capacity 容量
  • position 位置
  • limit 限制
  • 倆模式

  • 寫入模式
  • 讀取模式
  • 以上方的使用為例解析: 容量c,位置p,限制l

    [Write mode] 初始 0 1 2 3 ↑ ↑↑ p lc === put(x) === [Write mode] 完成put 0 1 2 3↑ ↑↑p lc === flip() === [Read mode] 轉換模式 0 1 2 3 ↑ ↑ ↑ p l c === get() === [Read mode] 完成get 0 1 2 3↑↑ ↑pl c === compact() === [Read mode] 清除已讀 0 1 2 3 x ↑↑ ↑ x pl c [Write mode] 并轉換模式 0 1 2 3↑ ↑↑p lc === clear() === 返回初始狀態 0 1 2 3 ↑ ↑↑ p lc 復制代碼

    2. Channel 通道

    運作方式:

    • BIO-Send: data -> byte[] -> outputStream
    • BIO-Receive: inputStream -> read -> data
    • NIO-Send: data -> buffer -> channel
    • NIO-Receive: channel -> buffer -> data

    API:

    • FileChannel
    • DatagramChannel
    • SocketChannel
    • ServerSocketChannel

    基本操作:

  • Client- SocketChannel
  • SocketChannel sc = SocketChannel.open(); sc.configureBlocking(false); // 設置為非阻塞模式 sc.connect( new InetSocketAddress("http://domain.com", port));sc.write(byteBuffer); sc.read(byteBuffer);sc.close(); 復制代碼
  • Server- ServerSocketChannel
  • ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); // 同理非阻塞 ssc.socket().bind(new InetSocketAddress(8080)); while(true){SocketChannel sc = ssc.accept();if( sc != null ){sc.write(xxx)sc.read(xxx)....} } 復制代碼

    Really? While loop? Need to be improved:

    3. Selector 選擇器

    用于管理多個NIO通道。

    channel事件類型使用SelectionKey常量來存儲:

  • 連接: SelectionKey.OP_CONNECT
  • 準備就緒: SelectionKey.OP_ACCEPT
  • 讀取: SelectionKey.OP_READ
  • 寫入: SelectionKey.OP_WRITE
  • 使用:

    // 創建選擇器 Selector selector = Selector.open(); selector.configureBlocking(false);ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); // 注冊通道 SelectionKey key = ssc.register(selector, SelectionKey.OP_READ);while(true){ // 一直監聽,安全保障int readyChannels = selector.select(); // 監聽事件,阻塞到有為止if( readyChannels == 0 ) continue; // 返回監聽狀態// 成功監聽到事件Set<SelectionKey> keys = selector.selectedKeys();Iterator<SelectionKey> keyIterator = keys.iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();// 判斷事件類型if (key.isAcceptable()) {// ...} else if (key.isReadable()) {// ...}keyIterator.remove();} } 復制代碼

    轉載于:https://juejin.im/post/5cad460d5188251b291b8773

    總結

    以上是生活随笔為你收集整理的Java知识积累-基础篇的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 水密桃av | 欧美日韩一区二区三区电影 | 免费在线观看成人 | 亚洲国产精品视频一区 | 午夜777 | 三年大全国语中文版免费播放 | 伊人亚洲综合 | 都市激情亚洲综合 | 人人澡超碰碰97碰碰碰 | 日本女人一区二区三区 | 狠狠婷婷 | 狂躁美女大bbbbbb黑人 | 欧美黑人xxxⅹ高潮交 | 国产美女三级无套内谢 | 婷婷天天| 男人天堂99| 可以免费看黄的网站 | 日本高清免费不卡视频 | 天天看片天天操 | 中国女人特级毛片 | 国产精品一区二区无线 | 国产日韩一区二区三免费高清 | 亚洲综合图 | 黄色网www | 中国老头性行为xxxx | 国产乡下妇女做爰毛片 | 国产熟女一区二区丰满 | 午夜男人影院 | 黄色片在线免费观看视频 | 国产欧美精品aaaaaa片 | 最近最新最好看的2019 | 天堂a√在线 | 欧美黄色特级视频 | 91精品国产一区二区三区香蕉 | 欧美精品综合 | 亚洲精品无码久久久久久久 | 黄色国产在线播放 | 色婷婷九月 | 91久久精品国产91性色tv | 国产精品日韩欧美一区二区三区 | 国产成人精品久久二区二区 | 全部孕妇毛片 | 亚洲激情自拍 | 美女调教视频 | 黑白配在线观看免费观看 | 99热这里都是精品 | 欧美在线免费看 | 欧美黑人精品一区二区不卡 | 久久国产麻豆 | 亚洲中国色老太 | 国产精品视频一区二区三区 | 午夜福利视频一区二区 | 久久久久久久成人 | 国产一级做a爱免费视频 | 亚洲毛片一区 | 国产精品一区二区三区高潮 | 成人黄色动漫在线观看 | 欧美黄色性视频 | 国产精品无套 | 操操插插 | 五月婷婷激情综合网 | 国产精品视频999 | 精品久久视频 | 国产农村妇女精品久久久 | 日韩1区| 欧美日a | 成人日皮视频 | 国产亚洲欧美一区 | 亚洲男人天堂av | 就要操就要日 | 国产小视频免费在线观看 | 欧美成免费 | 天天爽天天搞 | 麻豆91精品91久久久 | 手机在线精品视频 | 国产精品少妇 | www.色综合| 久久久久久中文 | 国产色在线观看 | 日韩精品视频一区二区三区 | 日本高清www | 韩国成人理伦片免费播放 | 在线免费观看黄色网址 | 亚洲4p | 又大又硬又爽免费视频 | 九九热这里只有 | 日本精品视频在线观看 | 日韩人妻精品中文字幕 | 91秘密入口 | 日韩欧美一区在线 | 一起草国产 | 日韩视频在线观看一区二区三区 | 日本黄色三级视频 | 男女黄色录像 | 免费看91| 日韩国产精品一区二区三区 | 午夜欧美激情 | 国产普通话bbwbbwbbw | 天堂av手机版 |