zoukankan      html  css  js  c++  java
  • JAVA学习前十天:小结、面向对象之”扑克牌“例子

    2016年4月26号正式步入JAVA学习课堂,学习了第一节JAVA课程,由于以前有C语言基础,所以课程有点快!

    第一天:学习了教材的第一部分,第一部分总共两章,分别是JAVA简介和JAVA基础语法。

    1. JAVA中字符用unicode编码,以前学的C是用ASCLL编码的,unicode编码完全包含ASCLL编码,并且还有很多事在ascll中没有的;
    2. JAVA中每一个小数常量默认为double型;
    3. 数据的转型操作中,自动转换就是将范围小的数据类型自动变为范围大的数据类型,强制转型是将范围大的数据类型转变为范围小的数据类型,转换方式有两种:数字F和(float)数字;
    4. JAVA中有一种数据类型叫布尔型(boolean),并且在JAVA中关系表达式的数据类型必须是boolean型。语句 int x=1>2在C语言中是对的,结果是x=0,而在JAVA中就是错的,因为1>2在JAVA中的数据类型是布尔型,x是整型,不能把结果为布尔型的结果赋值给整型。注:if语句内必须是布尔型。

    第二天:初步学习类与对象的概念,听得恍恍惚惚!

    第三天:继续学习类与对象

    1. 声明并实例化对象有两种格式:

        格式一,  对象名称 =new 类名称( )  ;

         例如:Person per = new Person();

        格式二,分步完成

          声明对象       类名称 对象名称 = null ;

          实例化对象    对象名称 = new 类名称();

        例如:

                     Person per =null;

                     per = new Person();

       2.定义一个类

        Package 包名

        Public class 类名

        {

           成员变量; //属性(名词,表特征)

           构造方法;

           成员函数;//方法(动词,表示行为)

        }

        属性和方法统称为类成员(member)。

       3.Java中指针占4个字节(java指针,什么鬼?),当一个对象没有任何指针指向它时,将会被系统回收,虽然Java本身提供了自动垃圾收集机制,但是在代码编写中,如果产生了过多的垃圾,则对于程序的性能也会带来影响,所以在开发人员编写代码的过程中应该尽量减少无用对象的产生,回避垃圾。

       4.然后讲了几个例子,对java封装一个初步的学习。

        成员变量名的第一个单词字母必须小写,后续单词的首字母大写。比如:userName,age,password,birthday等;

        成员变量对应的getter(setter)写法必须以get(set)开头,后续单词的首字母大写,比如:getUerName(setUerName),getPassword(setPassword),getAge(setAge)等。

    第四天:学习构造方法,this关键字,匿名对象等

       1.构造方法

        a.构造方法的名称和类名称保持一致;

        b.构造方法不允许由返回值类型声明;(没有return语句)

        c.一个类之中至少存在一个构造方法。

      默认情况下会存在一个无参的构造方法。

      class Person{         //类名称首字母大写

        public Person(){    //无参返回值的方法

             }

        }  

         2.this关键字

        a.“this.属性”表示本类属性;

        b.书上建议:日后的所有开发中,为了避免不必要的bug出现,只要是调用类中属性的情况,都要使用“this.属性"的方式进行表示;

        c.(this)调用本类方法

              所有的构造方法是在对象实例化时被默认调用的,而且是在调用普通方之前调用用,所以使用”this()“调用构造方法的操作一定要放在构造方法的首行。

          3.声明并开辟数组(也可以称为实例化数组)  

           数据类型 数组名称 []=new 数据类型 [长度];      int a[] =new int[3];

           数据类型 [] 数组名称 =new 数据类型 [长度];   int [] a=new int [3];

    第五天:二维数组

       1.动态初始化

        数据类型 数组名称 [][]=new 数据类型[行数][列数]   ;

        如,int a[][]=new int[7][8];

       2.静态初始化

        数据类型 数组名称 [][]=new 数据类型 [][]{{值,值,...},{值,值,...},...};

        如,int a[][]=new int[][]{{1,2,3},{54,6},{8,9,10,16}};

       3.对于数组data[][],

        data.length   行数

        data[i].length 列数(即i行的列数)

        在java中,每一行的列数可以不同(锯齿状数组)

    第六天:复习昨天的,理解java特性

    第七天:String类

       1. 两种不同的对象实例化方式

          采用直接赋值字符串的形式为String类对象实例化;

               如:String str="Hello",

          采用String类的构造方法为String类的对象实例化,String 类的构造为:public String(String str)

            如:String str =new String("String")

       2.字符串的比较

          String类中"=="和"equals()"的区别?

          a.==:比较的是两个字符串内存地址的数值是否相等,属于数值比较;

          b.equals():比较的是两个字符串的内容,属于内容比较。

       注:字符串常量本身是一个String类的匿名对象。什么是匿名对象?前面已经讲过,匿名对象就是指没有栈内存指向的堆内存空间,就是一个匿名对象。

    这里还讲到一个关于编译器优化的问题,比如String s="aa"+"bb"+"cc"在我们看来是占用了3个堆内存空间,但是经过编译器优化过后,就变成String s="aabbcc",从而会节省空间,这也是Java高级语言的神奇之处。

       3.String类两种实例化方式的区别

         直接赋值:String str=“Hello”;

                  如果String str1=“Hello”;

                        String str2=“Hello”;

                        String str3=“Hello”;

                  那么str1==str2==str3;

         解释:直接赋值操作中字符串都相同的原因:直接赋值会将字符串的内容放入到池中,以供其他继续使用直接赋值方式的String对象使用,如果新声明的字符串内容不再池中时,则会开辟一个新的,继续放入池中,以供下次使用。也就是说上面的3个String类,str1 str2 str3指向的是一个堆内存,这个堆内存中存的是“Hello”。

         构造方法赋值:String str=new String("Hello")

         因为每一个字符串都是一个String类的匿名对象,所以首先会在堆内存中开辟一块空间保存字符串“Hello”,而后又使用了关键字new,开辟了另一块堆内存空间,不过真正使用的是用关键字new开辟的堆内存,而之前定义的字符串常量的堆内存空间将不会有任何的栈内存指向,就会成为垃圾,等待被GC回收。所以在使用构造方法赋值时,实际上创建了两个String类的实例化对象。

        通过比较,在日后的所有开发中,String对象的实例化永远都采用直接赋值的方式完成。

       4.String类的常用方法。

        通过方法public int length()求出字符串s的长度;

        public int lastIndexOf(String str),表示从后向前查找字符串的位置,找不到返回-1;

        public int indexOf(String str,int fromIndex) 由指定位置向后查找字符串位置,找不到返回=-1;

    第八天:static关键字、单向链表等 

        static定义属性:static String country="北京";

        使用类名称访问static属性:static属性最好直接通过类名称来进行调用,使用“类名称.static属性”的方式来完成。

        Person.country=“北京”;

        可以在没有任何实例化对象时进行static属性的调用。

        static 定义的方法不能调用非static的方法或属性;

        非static定义的方法可以调用static的属性或方法。

    第九天:单向链表

    今天主要是学习上次没有学完的单向,话不多说,上代码!
    Node类:
    package com.cqvie.lianbiao;
    
    public class Node {
     public String data;
     public Node next;
    
    
    }

    Link类:

    package com.cqvie.lianbiao;
    
    public class Link {//带头节点的单向链表
      private Node head=null;
      public Link(){//构造方法
       head=new Node();
       head.next=null;
      }
         public void add(String data){//在末尾添加节点
          Node a=head;
          while(a.next!=null) a=a.next;//找尾节点
          Node tmp=new Node();//新建节点tmp
          tmp.data=data;
          tmp.next=null;
          a.next=tmp;//连接到尾节点之后
         }
         public void addAll(String data[]){
          
         }
         public int size(){//求链表的长度
          Node a=head;
          int n=0;
             while(a.next!=null) {
           n=n+1;
           a=a.next; 
          }
          return n;
         }
         public boolean isEmpty(){//判断链表是否为空
            return head.next==null;
         }
         public boolean contains(String data){//判断链表中是否含有某节点
          Node a=head;
          while(a.next!=null){
           a=a.next;
           if(a.data.equals(data))
            return true;
          }
          return false;
          
         }
         public void remove(String data){//删除一个节点
          Node p=head;
          Node q;
          while(p.next!=null){
           q=p;
           p=p.next;
           if(p.data.equals(data))
           q.next=p.next;   
          }
         }
         public String[] toArray(){
          return null;
         }
         public String get(int index){
          return null;
         }
         public void clear(){
          
         }
        public String print(){//将链表所有节点连接成一个字符串并输出
         Node a=head;
         String s="";
         while(a.next!=null){
             a=a.next;
             s+=a.data+"-->";
         }
         return s;
        }
    }

    Test类:

    package com.cqvie.lianbiao;
    
    public class Test {
    
     public static void main(String[] args) {
      Link link=new Link();
            link.add("节点1");
            link.add("节点2");
            link.add("节点3");
            System.out.println("这个链表是否为空:"+link.isEmpty());
            System.out.println("这个链表的长度:"+link.size());
            System.out.println("这个链表是:"+link.print());
            System.out.println("这个链表中是否有:“节点3”:"+link.contains("节点3"));
            link.remove("节点2");
            System.out.println("删除节点2后:"+link.print());
    
     }
    
    }

    输出结果:

    这个链表是否为空:false
    这个链表的长度:3
    这个链表是:节点1-->节点2-->节点3-->
    这个链表中是否有:“节点3”:true
    删除节点2后:节点1-->节点3-->

      今天的学习感觉到小吃力,主要是对JAVA的结构不熟,还有以前的C代码掌握不是很牢固,比如,删除节点的操作,在C中的代码没安全掌握,在这里换个结构,感觉很吃力。所以,基础很重要。这些还没写完,后天补五一假课,再战!

    第十天:链表、接口、继承性

      1.链表:今天接着前几天学习的java封装思想。还是链表那个例子,今天把这部分学完了。

    Node类:

    package com.cqvie.lianbiao;
    
    public class Node {
     public Object data;
     public Node next;
    }

    Link类:

    package com.cqvie.lianbiao;
    //有/**/的代码部分表示没有用tail来存尾指针,和size来存长度时的代码。其中61-63行(下划线)同理。
    public class Link {//带头节点的单向链表
      private Node head,tail;//tail存放尾节点指针
      private int size;//长度    
      public Link(){//构造方法
       head=new Node();
       head.next=null;
       tail=head;
      }
         public void add(Object data){//在末尾添加节点
      /*    Node a=head;
          while(a.next!=null) a=a.next;//找尾节点
          Node tmp=new Node();//新建节点tmp
          tmp.data=data;
          tmp.next=null;
          a.next=tmp;//连接到尾节点之后
       */
          Node tmp=new Node();
          tmp.data=data;
          tmp.next=null;
          tail.next=tmp;
          tail=tmp;//调整尾指针
          size++;//长度调整
         }
         public void addAll(Object data[]){
        /*  Node p=head;
          while(p.next!=null) p=p.next;//找尾结点
          for(int i=0;i<data.length;i++){
           Node tmp=new Node();//新建节点
           tmp.data=data[i];
           tmp.next=null;
           p.next=tmp;//连接到尾节点之后 
          }
        */
          for(int i=0;i<data.length;i++)
           this.add(data[i]);
         }
         public int size(){//求链表的长度
       /*   Node a=head;
          int n=0;
             while(a.next!=null) {
           n=n+1;
           a=a.next; 
          }
          return n;
        */
          return size;
         }
         public boolean isEmpty(){//判断链表是否为空也可用size是否为0判断
            return head.next==null;
         }
         public boolean contains(Object data){//判断链表中是否含有某节点
          Node a=head;
          while(a.next!=null){
           a=a.next;
           if(a.data.equals(data))
            return true;
          }
          return false;
          
         }
         public void remove(Object data){//删除一个节点
          Node p=head;
          Node q;
          while(p.next!=null){
           q=p;
           p=p.next;
           if(p.data.equals(data)){
           q.next=p.next; 
           if(p==tail)
              tail=q; 
              size--;
           } 
          }
          
         }
         public Object[] toArray(){
          return null;
         }
         public Object get(int index){
          Node a=head;
          int n=0;
          while(a!=null){
           if(n==index){
            return a.data;
           }
           n++;
           a=a.next;
          }
          return null;
         }
         public void clear(){
         //head.next=null;//这一句可以代替下面语句,但是直接断掉头节点,回收效率较低。
          Node a=head;
          Node b;
          while(a.next!=null){
           b=a.next;
           a.next=null;
           a=b;
           
          }
          tail=head;
          size=0;
         }
        public Object print(){//将链表所有节点连接成一个字符串并输出
         Node a=head;
         String s="";
         while(a.next!=null){
             a=a.next;
             s+=a.data+"-->";
         }
         return s;
        }
    }

    Test类:

    package com.cqvie.lianbiao;
    
    public class Test {
    
     public static void main(String[] args) {
          Link link=new Link();
          link.add("节点1");
            link.add("节点2");
            link.add("节点3");
            System.out.println("这个链表是:"+link.print());
            System.out.println("这个链表是否为空:"+link.isEmpty());
            System.out.println("这个链表的长度:"+link.size());
            
            System.out.println("这个链表中是否有:“节点3”:"+link.contains("节点3"));
            link.remove("节点2");
            System.out.println("删除节点2后:"+link.print());
            System.out.println("获得第一个节点:"+link.get(1));
    
        }
    
    }

    输出结果:

    这个链表是:节点1-->节点2-->节点3-->
    这个链表是否为空:false
    这个链表的长度:3
    这个链表中是否有:“节点3”:true
    删除节点2后:节点1-->节点3-->
    获得第一个节点:节点1

    上面这些代码,老师说在一个小时内,独立写出来,就是封装性入门了。

      2.继承

    然后讲了继承性:
    
    Animal:
    
    package com.cqvie.jicheng;
    
    public class Animal {
         private String name;
    
      public String getName() {
      return name;
     }
    
     public void setName(String name) {
      this.name = name;
     }
         public void tell(){
          System.out.println("动物叫");
         }
    }
    
     
    
    Cat:
    
    package com.cqvie.jicheng;
    
    
    public class Cat extends Animal{
        public void tell(){
         System.out.println("喵~");
        }
      }
    
     
    
     
    
    Dog:
    
    package com.cqvie.jicheng;
    
    public class Dog extends Animal {
        public void tell(){
         System.out.println("汪~");
        }
    }
    
     
    
    Sheep:
    
    package com.cqvie.jicheng;
    
    public class Dog extends Animal {
        public void tell(){
         System.out.println("汪~");
        }
    }
    
     
    
    Test:
    
    package com.cqvie.jicheng;
    
    public class Test {
    
     public static void main(String[] args) {
      Animal[] a=new Animal[4];
      a[0]=new Animal();
      a[1]=new Cat();
      a[2]=new Dog();
      a[3]=new Sheep();
      for(int i=0;i<a.length;i++)
       a[i].tell();
     }
    
    }
    
     
    
    输出结果:
    
    动物叫
    喵~~~

      3.接口

    还学了接口:
    
    USB:
    
    package USB;
    
    public interface USB {
         public void insert();//插入
         public void writeData(String s);//写入数据
         public String readData();//读取数据
         public void pop();//弹出
    }
    
    UDISk:
    
    package USB;
    
    public class UDisk implements USB {
    
     public void insert() {
      System.out.println("插入U盘");
    
     }
    
     public void writeData(String s) {
      System.out.println("写入数据"+s);
    
     }
    
     public String readData() {
            return "hello";
     }
    
     public void pop() {
      System.out.println("弹出U盘");
         
     }
    
    }
    
     
    
    Test:
    
    package USB;
    
    public class Test {
    
     public static void main(String[] args) {
      USB usb=new UDisk();
      usb.insert();
      usb.writeData("ABC");
      String s= usb.readData();
      System.out.println("读出:"+s);
      usb.pop();
    
     }
    
    }
    
    输出结果:
    
    插入U盘
    写入数据ABC
    读出:hello
    弹出U盘

    感想:

          一开始不了解或者说是对JAVA的特性不熟悉,不知道类与类之间的联系,对JAVA的封装,继承,多态不熟悉和没有更好的理解,在以后的学习过程中要掌握并熟悉JAVA的开发习惯,

    在写代码过程中还有众多东西没有掌握,靠着老师和同学的帮助完成这次学习,初步了解了JAVA面向对象开发的基本要领。写这个博客以便于自己今后学习,也算是一段美好的回忆吧!

    在后面这些天里,老师讲解知识点不只是小例子哦,还贯穿一个”扑克牌“的大例子来讲解java、让我们体会java:

    上面是一个类图  表示着写这个程序的只要思路。

    Card类:他的下级是cardview上级是player,有着一定的关系

    package com.cqvie;
    public class Card
    {
      public int rank,suit;
      public int cardIdx;
      public CardView cardView;
      public Player owner;
      public boolean selected=false;
      public static String suits[]
                                 =new String[]{"","♠","♥","♣","♦"};
      public static String ranks[]
                                 =new String[]{"J","Q","K","A","2","小王","大王"};
      
      public Card(int rank,int suit)
      {
        this.rank=rank;  this.suit=suit;
        this.cardView=new CardView(this); //在产生Card对象时,要同步产生CardView对象
      }
      public String toString()
      { 
       if(rank<=10) //10点或以下
        return suits[suit]+rank;
       else //10点以上
        return suits[suit]+ ranks[rank-11];
      }
    }

    CardView类:

    package com.cqvie;
    
    import java.awt.Font;
    import java.awt.Insets;
    import java.awt.Panel;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    
    public class CardView {
     private Card card; // 关联的Card
     private JButton btn;
     //private static JFrame win; // 依附的窗口
     
     public Card getCard() {
      return card;
     }
    
     public void setCard(Card card) {
      this.card = card;
     }
    
     public JButton getBtn() {
      return btn;
     }
    
     public void setBtn(JButton btn) {
      this.btn = btn;
     }
    
     public CardView(final Card card) {
      this.card = card;
      btn = new JButton();
      btn.setSize(50, 80);
      btn.setMargin(new Insets(0, 0, 0, 0)); //文字和控件的边距
      btn.setFont(new Font(btn.getFont().getName(), Font.BOLD, 16)); //字体设置
      btn.addMouseListener(new MouseAdapter() {
    
       @Override
       public void mouseClicked(MouseEvent e) {
        System.out.println(card.toString());
        card.selected=!card.selected;
        JButton b=(JButton)e.getSource();
        if(card.selected) b.setLocation(b.getX(),b.getY()-20);
        else b.setLocation(b.getX(),b.getY()+20);
       }
       
      });
     }
    
     public void show()
     {
      btn.setText(card.toString());
      int x=card.cardIdx*btn.getWidth()+50;
      //y=card.owner.payerIdx*150+50;
      btn.setLocation(x,20);
      this.card.owner.playerView.panel.add(btn);
     }
     
     public void refresh() //刷新按钮位置
     {
      int x=card.cardIdx*btn.getWidth()+50;
      btn.setLocation(x,20);  
     }
    }

    Player类:

    package com.cqvie;
    
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.LinkedList;
    import java.util.List;
    
    public class Player {
     //public String id;
     public int payerIdx;
     public boolean isLandlord;
     public List<Card> cards;
     public PlayerView playerView;
     public Player(int payerIdx)
     {
      this.payerIdx=payerIdx;
      isLandlord=false;
      cards=new LinkedList<Card>();
      this.playerView=new PlayerView(this);
     }
     
     public void putCards() //出牌
     {
      for(int i=cards.size()-1;i>=0;i--)
       if(cards.get(i).selected)
       {
        //从cards集合中删除card对象
        Card c= cards.remove(i);
        this.playerView.panel.remove(c.cardView.getBtn());
        //c.cardView.getBtn().setVisible(false);
       }
      //出牌后调整按钮位置
      for(int i=0;i<cards.size();i++) //更新cardIdx
      {
       cards.get(i).cardIdx=i;
       cards.get(i).cardView.refresh();
      }
      this.playerView.panel.repaint(); //刷新面板
     } 
     
     public void sortCards() //排序
     {
      Collections.sort(cards,new CardComparetor());
      for(int i=0;i<cards.size();i++) //更新cardIdx
       cards.get(i).cardIdx=i;
     }
    }
    
    class CardComparetor implements Comparator<Card>
    {
     @Override
     public int compare(Card o1, Card o2) {
      if(o1.rank!=o2.rank) return o2.rank-o1.rank;
      else return o1.suit-o2.suit;
     } 
    }

    PlayerView类:

    package com.cqvie;
    
    import java.awt.Color;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class PlayerView {
     public Player player;
     public JPanel panel;
     
     public PlayerView(Player p)
     {
      this.player=p;
      panel=new JPanel();
      panel.setLayout(null); //绝对布局
      panel.setSize(1300, 160);
      panel.setBackground(new Color(255, 255, 0));
     }
     
     public void show()
     {
      panel.setLocation(50, (panel.getHeight()+5)*player.payerIdx); 
      GameManager.win.add(panel);
      for(int i=0;i<this.player.cards.size();i++)
       this.player.cards.get(i).cardView.show();
      //显示玩家信息
      JLabel label=new JLabel();
      label.setSize(100,50);
      label.setLocation(50, 100);
      label.setText("玩家"+(this.player.payerIdx+1));
      panel.add(label);
      //添加“出牌”按钮
      JButton b=new JButton();
      b.setSize(80,40);
      b.setLocation(150, 120);
      b.setText("出牌");
      panel.add(b);
      b.addMouseListener(
        new MouseAdapter() {
    
         @Override
         public void mouseClicked(MouseEvent e) {
          player.putCards(); //player是外部类的属性
         }
         
        });
     }
    }

    GameManager类:

    package com.cqvie;
    
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Random;
    
    import javax.swing.JFrame;
    
    public class GameManager {
     public static JFrame win; //所属的窗口(公用)
     public Player[] players=null; //玩家集合
     public GameManager()
     {
      win=new MyWindow();
      players=new Player[3];
      for(int i=0;i<players.length;i++)
       players[i]=new Player(i);
     }
     public void startGame()
     {
      List<Card> cards=new LinkedList<Card>(); //扑克牌
      for(int i=3;i<=15;i++)
       for(int j=1;j<=4;j++)
        cards.add(new Card(i,j));
      
      cards.add(new Card(16,0));
      cards.add(new Card(17,0));
      
      Random r=new Random(); //随机数产生器
      for(int i=0;i<players.length;i++)
      {
       for(int j=0;j<17;j++)
       {
        int k=r.nextInt(cards.size());
        cards.get(k).owner=players[i];
        cards.get(k).cardIdx=j;
        players[i].cards.add(cards.get(k));
        cards.remove(k);
       }
       players[i].sortCards();
      }
      
         int t = (int)(Math.random() *players.length);
      players[t].isLandlord=true; 
      if(players[t].isLandlord)
        for(int m=17;m<=19;m++){
                 int k = (int)(Math.random() * cards.size());
                 cards.get(k).owner=players[t]; 
                 cards.get(k).cardIdx=m;
                 players[t].cards.add(cards.get(k));
                 cards.remove(k); 
       }
      players[t].sortCards();
      
    //  for(int i=0;i<players.length;i++)
    //  {
    //   System.out.print(players[i].id+players[i].isLandlord+"的牌是");
    //   players[i].cards.print();
    //   System.out.print("
    ------------------------
    ");
    //  }
     }
     
     public void show()
     {
    //  for(int i=0;i<players.length;i++)
    //   for(int j=0;j<players[i].cards.size();j++)
    //   {
    //    players[i].cards.get(j).cardView.show();
    //   }
      for(int i=0;i<players.length;i++)
       players[i].playerView.show();
      win.setVisible(true);
     }
    }

    窗口(win)类:

    package com.cqvie;
    
    import javax.swing.*;
    
    public class MyWindow extends JFrame {
     public MyWindow() {
      this.setSize(1500, 800);
      this.setLayout(null); 
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     }
    
    }

    Test类:

    package com.cqvie;
    
    public class Test {
    
     public static void main(String[] args) {
    
      GameManager gm=new GameManager();
      gm.startGame();
      gm.show();
      
     }
    
    }

     欢迎联系小编探讨技术、聊聊人生。
    QQ:34782655 点击聊天
    微信公众号:敲代码的小松鼠

  • 相关阅读:
    设计模式之备忘录模式
    特殊传参方式
    页面响应效率测试
    composer安装的包git无法提交的解决办法是因为安装的时候生成了.git隐藏文件
    数据结构和算法深入浅出理解
    中缀表达式转换为后缀表达式
    p2p技术
    【自动化测试】WebDriver使用
    pt-query-digest简介使用
    mac编译openJDK8
  • 原文地址:https://www.cnblogs.com/hyyq/p/5574346.html
Copyright © 2011-2022 走看看