1-集合

1.链表、二叉树

一些常见数据结构:

数组:增删慢、查找快,相邻元素内存地址相邻,当数据量大时动态扩容效率低而且非常耗费性能。

链表:增删快、查找慢,当数据量大时查找元素很慢,需要从头开始逐个遍历。链表可以分为单向链表、循环链表、双向链表、双向循环链表。

二叉树:类似于链表,只不过链表只有一个指向next,而二叉树有两个指向即left和right。如果二叉树存储有序元素(例如比根节点小存左子树,比根节点大存右子树),考虑二叉树平衡的情况,当查找一个元素时,每次比较都可以将查找范围缩小一半,类似于二分查找,查找效率非常高。

栈stack:先进后出,操作:压栈、弹栈

队列queue:先进先出,操作:入队、出队。也存在双向队列,即两边都可以出入队。

2.集合

集合即容器,用来存储数据的结构。java内置了非常成熟的容器,集合在java.util包下

如何对这些容器中的元素遍历呢?可以使用Iterator迭代器,通过iterator()可以实现对集合中所有元素的遍历。

集合按照其存储结构可分为两大类:Collection是单列集合,Map是双列集合。

collection接口中定义的方法:

通常使用中不会直接使用Collection接口,而是使用其子接口ListSet。其中list中允许元素重复,set不允许元素重复

3.List接口(重点)

list接口的实现类:ArrayList(95%)(数组实现)、Vector(4%)(数组实现)、LinkedList(1%)(双端链表实现),Vector可以看作ArrayList的早期版本。vector是线程安全的,arraylist是非线程安全的。如果不需要线程安全,推荐使用ArrayList代替Vector。(线程安全会降低性能)

4.ArrayList类(重点)

数组实现,动态扩容每次1.5倍。默认大小是10,如果明确知道arraylist要存很多数据,就要给定初始值大小,否则会浪费很多内存在扩容上,会降低性能。

初始化大小10是在扩容操作中实现的。查看源码弄清楚扩容流程。

如果有参构造提供初始大小,则直接创建对应大小的数组,这一过程不需要扩容。

如果通过无参构造,默认赋值一个空数组,在首次添加元素时,进行扩容,数组默认长度为10,扩容是通过Arrays.copyOf实现的

5.Vector类

数组实现。方法与ArrayList一致,多了一个构造方法,该方法多了一个参数即增量大小。Vector默认增量大小是0,如果增量大小>0每次扩容按照增量大小进行扩容,否则安装2倍大小扩容。

6.LinkedList类

双向链表实现。不仅可以用作list,还可以当作栈、单端队列、双端队列来使用。

栈的操作:push()入栈、pop()出栈

队列操作:addFirst(),addLast()、removeFirst()、removeLast()、getFirst()、getLast()

7.Iterator和ListIterator迭代器

迭代器只能迭代Collection集合,即list和set

iterater:hasNext()、next()等等

ListIterator:是Iterator的子类接口,除了上面的方法还有 hasPrevious()和previous()、add()、remove()等

8.for each增强遍历

遍历数组或集合,集合只能是Collection,即list和set

9.Set接口

Set实现类:HashSetTreeSetLinkedHashSet

基本上和Collection方法一致,仅添加了少许几个方法。

注意:Set中并没有get()方法,如果想要遍历一个set,可以通过iterator或者调用toArray()生成一个数组并对数组进行遍历。

10.HashSet类

hashset内部使用了hashmap(也叫做散列表),存储的数据是无序的,不能保证存储顺序。add方法在内部是调用了hashmap的put方法。

Set类如何保证值的不重复?答案是使用map类,因为map类存储的键值对,而键是不可重复的,所以利用这一点可以实现不重复。

11.TreeSet类和Comparable接口

内部是使用TreeMap实现的。TreeSet采用了二叉树存储,是有序的。

TreeSet和TreeMap若是存储自定义的类需实现Comparable接口,否则不能使用。

集合的迭代器一般是安全失败的,TreeSet的迭代器是快速失败的。

安全失败的意思:当一个迭代器对这个集合遍历时会首先把数据拷贝一份,对拷贝数据进行迭代,这样即使在遍历过程中其他线程对这个集合进行了修改也不会出错。而快速失败就是不加拷贝,直接对集合进行遍历,但若有其他线程对集合数据进行了增删修改,就会出错。

TreeSet是有序的,排序的类需要实现Comparable<>接口并重写compareTo方法,<>中是需要排序的类型。

public class TreeSetTest {public static void main(String[] args) {TreeSet<Person> set = new TreeSet<>();Person p1 = new Person("张三", 20);Person p2 = new Person("李四", 30);Person p3 = new Person("王二", 10);set.add(p1);set.add(p2);set.add(p3);for (Person p :set) System.out.println(p);}static class Person implements Comparable<Person>{private String name;private int age;//重写此方法自定义排序规则,//return值说明:负数this小,0相等,正数this大@Overridepublic int compareTo(Person o) {if (age<o.age)return -1;else if (age > o.age) return 1;return 0;}@Overridepublic String toString() {return "Person{" +"name='" + name + "\'" +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Person(String 张三, String s) {}public Person(String name, int age) {this.name = name;this.age = age;}}
}

12.Map接口

Map的实现类:HashMapHashTableConcurrentHashMapTreeMapLinkedHashMap操作都是一样的。

存数据:put()

删除数据:remove(),会返回删除的这个数据,有些数据使用一次就不再使用了就可以使用remove()删除并获取

获取数据:get()

遍历数据:通过keySet()

遍历一个Map比较麻烦,可以使用keySet()获取所有键的set集合,通过遍历set中的键可以遍历所有值。

其他方法:containsKey()、containsValue()、size()、

values()将所有的值转换成collection集合,用的非常少。

13.HashMap类

hashMap原理图:

根据我的面试经验来看,hashmap是面试被问的最多的数据结构,没有之一,其次就是list。查看实现原理,而hashmap最重要的就是resize扩容方法!必须吃透源码!必须吃透源码!必须吃透源码!

  • 作为HashMap键的那个类必须重写equals和hashCode方法

  • HashMap存储自定义对象时,如果自定义对象是键,则不要随意更改对象的数据,否则将查找不到原数据,例如:

    public class Test{public static void main(String[] args) {HashMap<Book, String> map = new HashMap<>();Book book1 = new Book("金苹果", "讲述了金苹果的故事。");map.put(book1,"这是第一本书");Book book2 = new Book("银苹果", "讲述了银苹果的故事。");map.put(book2,"这是第二本书");//将book1的name进行修改book1.setName("铜苹果");//get方法将根据book1的hashCode查找位置,找到位置后再进行equals比较//打印结果为null System.out.println(map.get(book1));}static class Book{private String name;private String info;public Book(String name, String info) {this.name = name;this.info = info;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Book book = (Book) o;return Objects.equals(name, book.name) &&Objects.equals(info, book.info);}//计算hashCode是根据name和info的值计算的,如果这两个属性的值被修改,//计算出的hashcode就会改变@Overridepublic int hashCode() {return Objects.hash(name, info);}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}}
    }

14.HashMapHashTableConcurrentHashMap区别

TreeMap不保证存储顺序但会对元素进行排序(根据键排序),LinkedHashMap可以保证存储顺序。实现原理是同时使用HashMap和双向链表保存数据,双向链表保证了存储顺序。

15.JDK9集合新特性

List、Set、Map 这三个接口中提供了一些静态方法,of(),该方法可以创建固定长度的集合,不可向集合中添加、删除元素。

 public static void main(String[] args) {List<Book> list = List.of(new Book("1","100"),new Book("2","200"));//r   //list.remove(0);for (Book s :list) {System.out.println(s);}}

2.

1.实现一个单链表

在这个实现中,使用了泛型,实现了添加数据、指定位置添加数据、删除指定位置数据、获取指定位置数据、获取size的一些操作。

public class SingleList<a> {private Node<a> head;private int size;//添加一个数据,默认是添加到结尾public boolean add(a data){Node<a> cur = new Node<>(data);if (head==null)head = cur;else{Node tmp = head;while (tmp.getNext()!=null){tmp = tmp.getNext();}tmp.setNext(cur);}size++;return true;}//指定位置插入数据public boolean add(a data,int index){if (index>=size){throw new RuntimeException("下标越界异常!index:"+index+",size:"+size);}else{Node<a> cur = new Node<>(data);if (index == 0){cur.setNext(head);head = cur;}else{Node tmp = head;index-=1;while (index-->0){tmp=tmp.getNext();}cur.setNext(tmp.getNext());tmp.setNext(cur);}size++;return true;}}//指定位置删除public a delete(int index){if (index>=size)throw new RuntimeException("下标越界异常!index:"+index+",size:"+size);else{a data;if (index == 0){data = head.getData();head = head.getNext();}else{Node<a> right = head;Node left = null;while (index-->0){left = right;right = right.getNext();}data = right.getData();left.setNext(right.getNext());right.setNext(null);}size--;return data;}}//获取指定位置的数据public a get(int index){if (index>=size)throw new RuntimeException("下标越界异常!index:"+index+",size:"+size);else {Node<a> tmp = head;while (index-->0){tmp = tmp.getNext();}return tmp.getData();}}//打印当前链表public void print(){Node tmp = head;while (tmp!=null){System.out.println(tmp.getData());tmp = tmp.getNext();}}//返回节点个数public int size(){return this.size;}
}
//节点的定义
class Node<T>{private T data;private Node<T> next;public Node() {}public Node(T data) {this.data = data;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Node<T> getNext() {return next;}public void setNext(Node<T> next) {this.next = next;}
}

2.二叉树的遍历

遍历二叉树通常有两种方式:广度优先搜索(BFS)、深度优先搜索(DFS)

说到底,搜索就是遍历,XX搜索不就是遍历某种数据结构的方法吗?搞这么专业的名词就是用来唬人的,广度优先搜索就是按层去遍历,深度优先搜索就是按深度去遍历。其中深度优先搜索又分为三种方式:

先序遍历、中序遍历、后序遍历。

首先来看广度优先搜索

BFS和DFS

LinkedList可以当作list使用,也可以当作queue使用,还可以当作stack使用。BFS一般需要借助queue来实现。

DFS一般是递归实现,也可以通过循环实现,但非常麻烦。

前序:根左右。中序:左根右。后序:左右根。

三种方式无非是打印根节点的时间不一样,前序先打印根,中序中间打印根,后续最后打印根。

import java.util.LinkedList;public class Tree {public static void main(String[] args) {//创建7个节点TreeNode<Integer> root = new TreeNode<>(1);TreeNode<Integer> node2 = new TreeNode<>(2);TreeNode<Integer> node3 = new TreeNode<>(3);TreeNode<Integer> node4 = new TreeNode<>(4);TreeNode<Integer> node5 = new TreeNode<>(5);TreeNode<Integer> node6 = new TreeNode<>(6);TreeNode<Integer> node7 = new TreeNode<>(7);//手动构建一棵树root.setLeft(node2);root.setRight(node3);node2.setLeft(node4);node2.setRight(node5);node3.setLeft(node6);node3.setRight(node7);//测试广度优先搜索BFS(root);//测试深度优先搜索DFS(root);}static void BFS(TreeNode root){LinkedList<TreeNode> queue = new LinkedList<>();//首先将根节点放入队列queue.addLast(root);int i = 0;while (queue.size()>0){i++;TreeNode cur;//size为该层节点的个数int size = queue.size();System.out.print("第"+i+"层数据:");while (size-->0){//获取第一个节点为当前节点curcur = queue.removeFirst();//将此节点的左右节点放入队列if (cur.getLeft()!=null)queue.addLast(cur.getLeft());if (cur.getRight()!=null)queue.addLast(cur.getRight());//输出这一层的数据,不换行System.out.print(cur.getData()+"\t");}//每输出完一层需要换行System.out.println();}} //DFS  static void DFS(TreeNode root){if (root == null)return;if (root.getLeft()!=null)DFS(root.getLeft());if (root.getRight()!=null)DFS(root.getRight());System.out.print(root.getData()+"\t");}
}
//定义树节点
class TreeNode<T>{private T data;private TreeNode left;private TreeNode right;public TreeNode() {}public T getData() {return data;}public void setData(T data) {this.data = data;}public TreeNode getLeft() {return left;}public void setLeft(TreeNode left) {this.left = left;}public TreeNode getRight() {return right;}public void setRight(TreeNode right) {this.right = right;}public TreeNode(T data) {this.data = data;}
}

3.构建二叉排序树

上面通过手动构建了一棵二叉树,二叉树相较于链表最大的优势就在于二叉树可以对数据进行排序,一棵平衡的有序二叉树查找元素的效率非常高,性能接近于二分查找,所以如何构建有序二叉树呢?

有序二叉树的中序输出即为排好序的数据

public class BinarySortTree {private TreeNode<Integer> root;//添加数据public boolean add(Integer data){if (root == null){root = new TreeNode<>(data);return true;}else{TreeNode<Integer> cur = root;TreeNode<Integer> parent ;while(cur!=null){parent = cur;if (data<cur.getData()){cur = cur.getLeft();if (cur == null){parent.setLeft( new TreeNode<>(data));return true;}}else{cur= cur.getRight();if (cur == null){parent.setRight( new TreeNode<>(data));return true;}}}}return false;}//查找目标值//这种查找方式是借助了二叉排序树的特点,只有是二叉排序树才能这样查找数据public TreeNode<Integer> get(Integer target){TreeNode<Integer> cur = root;while (cur!=null){if (cur.getData() == target)return cur;else if (target<cur.getData())cur = cur.getLeft();else cur = cur.getRight();}return null;}//获取根节点public TreeNode getRoot(){return root;}
}
//测试
public static void main(String[] args) {BinarySortTree binarySortTree = new BinarySortTree();int[] num = {2,4,5,1,3,4,0};for (int i = 0; i < 7; i++) {binarySortTree.add(num[i]);}TreeNode root = binarySortTree.getRoot();//DFS的中序输出即为 0 1 2 3 4 4 5Tree.DFS(root);
}

4.IO

talk is cheap show me code

//三种创建文件的方式
public static void main(String[] args) throws IOException {File dir = new File("z://haha");//创建haha文件夹//System.out.println(dir.mkdir());File a = new File(dir, "a.txt");System.out.println(a.createNewFile());File b = new File("z:haha", "b.txt");System.out.println(b.createNewFile());//删除文件a.delete();b.delete();}

其他一些常用方法:

  • getAbsolutePath()获取绝对路径,例如:z://haha
    length()获取文件的长度,即大小,单位是字节
    getPath()、getParent()、getParentFile()
    exist()判断一个文件是否存在
    list()、listFile()、
    renameTo()重命名绝对路径,可以看作移动位置并重命名
    

    以下是一个遍历文件夹的例子:遍历z盘并找到所有MP4文件

public class SearchAllDir {public static void main(String[] args) {File z = new File("z:");File[] list = z.listFiles();search(list);}//传入File数组static void search(File[] list){//如果不为null且长度大于0if (list!=null&&list.length>0){//遍历文件for (File file : list) {//如果是文件if (file.isFile()){//匹配以.mp4结尾的文件并输出其绝对路径,还可以加上对大小的判断if (file.getName().endsWith(".mp4")){System.out.println("找到一个mp4:"+file.getAbsolutePath());}}//否则是文件夹,递归搜索else{search(file.listFiles());}}}}
}
4.1相对路径

在java中相对路径根目录是项目目录。

例如:

 File a = new File("a.txt");System.out.println(a.getAbsolutePath());
//在Test项目中,打印结果如下:

5.IO流

IO流分类:

1.按照流的方向:输入流和输出流

2.按照流动的数据类型分类:字节流和字符流

注意:字符流也来自字节流,只不过字符流对字节流进行了一些处理,

一般使用字节流较多,但通过字节流读取文字可能会乱码,所以读取文字一般使用字符流。

任何流在传输时都是二进制

顶级父类如下:

  • 字节流

    • 输入流:InputStream
    • 输出流:OutputStream
  • 字符流:
    • 输入流:Reader
    • 输出流:Writer

6.OutputStream输出流

任何流,在使用完之后都应该尽可能早的调用close()关闭流。

有一个例子:有时候我们要关闭某个文件却关不掉,原因就是有其他某个进程在读取这个文件没有关闭流。

常用方法:close()、flush()刷新输出流并强制写出缓冲区、write()写入输出流

输出流用的最多的就是FileOutputStream

6.1FileOutputStream

常用方法:构造方法、close方法、write方法

创建一个流输出时默认是清空文件后再输入,也可以添加参数true,就变成追加模式。在一个流close()前的多次输出都是追加的。

//这样创建流默认是清空文件再输出
FileOutputStream fos = new FileOutputStream("z:\\IO\\io.txt");
//这样创建流是追加输出
FileOutputStream fos = new FileOutputStream("z:\\IO\\io.txt",true);//传入int类型 int类型只有0-255有效,即低8位有效,后面24位都没用 65输出就是'A'
fos.write(65);
//传入一个byte[],这样用的并不多,因为文字一般使用字符输出流
fos.write("你好今天天气真好!&*)!".getBytes());
//传入byte[]数组,并指定开始下标和长度。
byte[] bytes = "ABCDE".getBytes();
fos.write(bytes,2,3);

三种输出方式:

7.InputStream输出流

InputStream中最常用的子类就是FileInputStream类。

7.1FileInputStream

常用方法还是三个:构造方法、close方法、read方法。read方法可以单字节读取,但更常用的是每次读取一个byte数组,这样可以减少IO次数。

例如,读取一个1MB的文件,如果单字节读取需要读取1024*1024次,但如果定义一个大小为1024*1024的byte数组,读取一次就可以了。

//read每次读取一个字节,得到的是int类型,如果没有内容则返回-1
public static void main(String[] args) throws IOException {//io.txt中内容是ABCDEFileInputStream fis = new FileInputStream("z:\\IO\\io.txt");int flag;while (true){flag = fis.read();if (flag==-1)break;System.out.println((char) flag);}fis.close();}
//read(byte[] bytes)每次将读取的结果放入bytes数组中,io.txt中是A-Zpublic static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("z:\\IO\\io.txt");byte[] bytes = new byte[10];fis.read(bytes);//通过new String(byte[] bytes)可以构造字符串System.out.println(new String(bytes));fis.read(bytes);System.out.println(new String(bytes));fis.read(bytes);System.out.println(new String(bytes));fis.close();}

打印结果如下:

可以发现,最后有四位是重复的,而qrst是上次读取的内容,读取到z后没有内容了,就没办法覆盖后四位了。

如何解决?

//io.txt中是A-Z
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("z:\\IO\\io.txt");byte[] bytes = new byte[10];int len = 0;while (len!=-1){//read(byte[] bytes)返回读取的字节长度,前两次都读取了10个字节,长度为10,//第三次读取了6个字节,返回6,第四次由于没有内容了,返回-1len = fis.read(bytes);if (len == -1)break;//0代表起始位置,len代表长度System.out.println(new String(bytes,0,len));}fis.close();}

打印结果如下:

8.编码表

最初只有ASCII码,只能表示英文字母、阿拉伯数字和一些常见符号。随着发展各国语言都有自己对应的编码表,为了解决各国编码不统一的问题,出现了utf-8编码,utf-8是一种可变长的编码表。长度可以是1-4个字节。

8.1字节流读取文字的问题

由于utf-8是可变长的,所以通过字节流读取中文可能会出现读一半汉字的情况,如图:

如果是乱码还比较容易解决,但这种读一半文字的情况就难以解决。为了解决这个问题,所以在读取文字时都是使用字节流。

9.字符流输出字符

FileWriter
    public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("z:\\IO\\io.txt");//append方法返回调用者本身,所以可以连续调用,即链式调用fw.append("你好!").append("张三风",0,2);fw.close();}

10.字符流读取字符

FileReader
//演示了每次读取一组字符
public static void main(String[] args) throws IOException {FileReader fr = new FileReader("z:\\IO\\io.txt");char[] res = new char[2];while (true){int len = fr.read(res);if (len == -1)break;//读取多少长度,就输出多少长度,记得从0-lenSystem.out.println(new String(res,0,len));}}

flush,将缓冲区的字符强制输出。close()方法中也调用了flush方法。字符流在读取字符后一定要刷新管道!

11.转换流(将字节流转换成字符流)–装饰者模式

假设字节流是获取到的,代码中手动创建了。

12.Properties

将配置输出到指定位置或者从指定位置读取配置。

    public static void main(String[] args) throws IOException {/*        Properties ppt = new Properties();ppt.setProperty("												

java学习笔记-2相关推荐

  1. java学习笔记11--Annotation

    java学习笔记11--Annotation Annotation:在JDK1.5之后增加的一个新特性,这种特性被称为元数据特性,在JDK1.5之后称为注释,即:使用注释的方式加入一些程序的信息. j ...

  2. java学习笔记13--反射机制与动态代理

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note13.html,转载请注明源地址. Java的反射机制 在Java运行时环境中,对于任意 ...

  3. 准备写java学习笔记

    准备写java学习笔记 java int 转载于:https://blog.51cto.com/cryingcloud/1975267

  4. Java学习笔记--StringTokenizer的使用

    2019独角兽企业重金招聘Python工程师标准>>> Java Tips: 使用Pattern.split替代String.split String.split方法很常用,用于切割 ...

  5. java学习笔记12--异常处理

    java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 j ...

  6. Java学习笔记(十)--控制台输入输出

    输入输出 一.控制台输入 在程序运行中要获取用户的输入数据来控制程序,我们要使用到 java.util 包中的 Scanner 类.当然 Java 中还可以使用其他的输入方式,但这里主要讲解 Scan ...

  7. java学习笔记16--I/O流和文件

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input  Output)流 IO流用来处理 ...

  8. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  9. java学习笔记14--多线程编程基础1

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...

  10. java学习笔记11--集合总结

    java学习笔记系列: java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Ob ...

最新文章

  1. 走过2011,展望2012
  2. 如何配置Filter过滤器处理JSP中文乱码
  3. 区块链基础语言(三)——Go语言开发工具
  4. 演练 宠物店挑小动物 java 1615136001
  5. AttributedString 图片间距问题
  6. Build your own distribution based on Fedora CoreOS
  7. 几个 XmlTextReader 的例子, 帮了我大忙.
  8. 一键刷入twrp工具_OPPORealme X 刷入原生lineage16-AOSP纯净系统完美ROOT 刷机必备
  9. mysql mycat docker_docker-mycat-mysql
  10. java 关键字 val,java关键字final用法知识点
  11. jQuery事件与事件对象
  12. 青岛地区服务器不稳定怎么办,青岛联通现大面积DNS故障 用户该如何上网
  13. 工业相机 镜头 焦距 视野 计算相关
  14. java非主流火星文输入法_我爱火星文_火星文输入法
  15. 【Rust日报】 2019-04-09
  16. (trigger)触发器的定义和作用
  17. 网络协议分析期末复习专题(二)
  18. PHP 开发经验教训
  19. 编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:
  20. 求助松下笔记本电脑的WLAN问题

热门文章

  1. 通过自定义Gradle插件修改编译后的class文件
  2. linux怎么在目录下查找文件,linux find-在指定目录下查找文件
  3. git clone提速(好用的github镜像)
  4. Linux目录文件的权限,默认权限,隐藏权限
  5. 量子特性应用之一:量子密钥分发
  6. Android 微信支付调不起
  7. visual studio .vcxproj
  8. 直播预告 | 罗切斯特大学张宋扬、英国剑桥大学刘方宇
  9. React Native从零开始(七)Fetch网络请求
  10. 华为机试-求int型数据在内存中存储时1的个数