JavaSE学习笔记

一、java的基本语法

变量运算规则


编码情况1中l后面没有加L,默认是int变量
编码情况2中b1=b+1中的1默认是int型变量,会出错

string类型


string里面可以从0个字符开始赋值,但是char的‘’里面至少有一个字符


如果“+”前后有一个数据类型是string类型,那么就是在做连接运算,如果两个都不是string类型,那就是在做加法运算


输出结果:

像下面的\t注意要用双引号,不能用单引号,不然就成了加法运算而不是连接运算

第二种全是char型变量,相加会输出int型变量,第四种前两个变量相加会输出int型变量


不可以把string类型的强制转为int型,只可以做连接运算


string类型在常量池中,重新定义一个对象,如果常量池有了,那么它会复用已存在的

String s1 = "BB";
String s2 = "BB";
System.out.println(s1 == s2);//true

之前用==判断String 不是判断常量池的内容 是用两个String类型的对象进行比较 那时候比较的是对象地址值 而不是内容!
注意区分字符串常量和字符串对象,一个指向常量池,一个指向堆中
所以后面在重写类的equals时注意比较string时要用string类自己重写的equals

         //正确的:return this.orderId == order.orderId && this.orderName.equals(order.orderName);//错误的:
//          return this.orderId == order.orderId &&
//                  this.orderName == order.orderName;

注意:在JDK6.0及之前版本,字符串常量池存放在方法区中在JDK7.0版本以后,字符串常量池被移到了堆中了

运算符

自增运算符不会改变本身变量的数据类型



编译失败的2是int型



*=也不会改变数据类型,也是输出int型,会截断输出0



最后一个是12的原因:前一个操作n已经变成了11,最后一个++n,先自增,所以+的是12


区别位运算符和逻辑运算符:位运算符前后都是数,逻辑运算符前后都是布尔型



==:对于引用数据类型来讲,比较的是两个引用数据类型变量的地址值是否相同


三元运算符

:前后的两个类型要求是一致的
Integer与Double在三元运算符中先转换成int与double基本数据类型去做比较,返回的结果是double1.0会再转化成包装类赋给o1

 public void test1() {Object o1 = true ? new Integer(1) : new Double(2.0);System.out.println(o1);// 1.0,自动类型提升,所以输出1.0}

if-else


()里面不要这样写,80<score会生成一个bool类型,会报错
else if里面的条件表达式正确时,不会再执行下面的if-else了

else遵循就近原则,所以输出的是x
“是”.equals(str)函数判断.前面的字符是否和()里面的字符一样

switch case


一些合并的写法


三元表达式-if-switch之间的关系
都可以转换成if表达式,但是反之不成立


下面代码里面如果没有break的话,前面定义的money和info会延续到后面继续使用,一般来说支出金额要重新定义一个名字,eg:addMoney,minusMoney

循环

for循环里面的i只在for循环里面有效

二、数组

动态定长度,静态定元素

char数组:元素的默认初始化值是0,非‘0’,打印出来的效果跟空格一样,实际上并不是空格
空格对应的数值是32,空字符对应的数值才是0,字符’0’对应的数值是48

字符串属于引用类型

放在main函数中的变量都叫局部变量,局部变量放在栈当中

二维数组

定义时也可以像下面这样定义

下面是一些错误例子,前面的两个括号里面不能写数字,也不能动静态初始化混用

总结:

数组赋值是新开辟一个数组,进行每一个元素的赋值,而不是直接用新数组=旧数组来操作,这样只是指向地址相同

三、面向对象

值传递

和数组的情况类似,这种是地址赋值,修改属性值时其他指向同一个地址的类的属性值也会变化


arr数组调用的是println(Object)函数,输出地址值
arr数组调用的是println(char[])函数,这个函数的方法体里面是遍历输出的代码,所以不会输出地址值



这段代码输出的是hello,虽然string是引用数据类型,但是它比较特殊
原因:
string是引用数据类型,在常量池中创建了一个char型数组存放了hello,再将这个hello的地址值赋给了s1,接着将s1赋给了s,s和s1指向同一块地址,此时s1也指向hello的地址,因为string的底层是用char数组进行存放的,所以在给s赋值“hi~~”时,又会创建一个新的char数组,来存放“hi”将这个新char数组的地址赋给s,所以s1的指向依旧是hello,最终输出hello


封装性

封装性的体现:
四种权限也可以体现为封装性的一种


综合练习一:customer和account

Account是一个public的类,可以在另一个类中定义成一个属性,参考string,string也是一个类,它也可以这样定义

customer手上有账号account,每一个用户对应一个账户,所以在用户类里面又定义了账户类,通过用户类去操作账户类



import关键字

import static组合的使用:调用指定类或接口下的静态的属性或方法
表示import的是system下的一些静态属性或者方法原来的代码:

原来的代码:
out前面删掉了string

就可以改写成下面的写法

out是string类中定义的一个属性


import 和import static的区别:
import的落脚点是类
import static的落脚点是类中的一个结构


继承性

子类会继承父类中的所有属性和方法,但是能不能访问又是另外一回事了

方法重写

编译器认为int…和int[]是一样的,在方法重写时要注意



子类重写的方法的返回值类型必须是相同的基本数据类型(比如:double)


四种访问权限修饰符



总结:
1、对于在同一个包下的父类中的属性和方法,除了private修饰的,其他的都可以被子类调用;
2、对于不同包下的父类中的属性和方法,除了private和缺省修饰的,其他的都可以被子类调用;
3、对于不同包下的普通类(非子类),只能调用public


super

子类中的多个构造器中至少有一个构造器中用super(形参列表)

子类对象实例化


1).为什么super(…)和this(…)调用语句不能同时在一个构造器中出现?
因为二者都必须出现在首行
2).为什么super(…)或this(…)调用语句只能作为构造器中的第一句出现?
无论通过哪个构造器创建子类对象,需要保证先初始化父类。
目的:当子类继承父类侯,“继承”父类中所有的属性和方法,因此子类有必要知道父类如何为对象进行初始化

多态性

对象的多态性:在编译期,只能调用父类中声明的方法,但在运行期,实际执行的是子类重写父类的方法。多态是运行时行为,因为方法调用在编译器是无法确定的
属性不存在多态性
属性(编译和运行都看左边)


多态性的使用举例:
好处:减少了方法的重载

package com.atguigu.java4;import java.sql.Connection;//多态性的使用举例一:
public class AnimalTest {public static void main(String[] args) {AnimalTest test = new AnimalTest();test.func(new Dog());test.func(new Cat());}public void func(Animal animal){//Animal animal = new Dog();animal.eat();animal.shout();if(animal instanceof Dog){Dog d = (Dog)animal;d.watchDoor();}}//  public void func(Dog dog){//      dog.eat();
//      dog.shout();
//  }
//  public void func(Cat cat){//      cat.eat();
//      cat.shout();
//  }
}class Animal{public void eat(){System.out.println("动物:进食");}public void shout(){System.out.println("动物:叫");}}class Dog extends Animal{public void eat(){System.out.println("狗吃骨头");}public void shout(){System.out.println("汪!汪!汪!");}public void watchDoor(){System.out.println("看门");}
}
class Cat extends Animal{public void eat(){System.out.println("猫吃鱼");}public void shout(){System.out.println("喵!喵!喵!");}
}//举例二:
//只要是一个对象都可以调用这个方法
class Order{public void method(Object obj){}
}//举例三:
class Driver{public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();//规范的步骤去操作数据
//      conn.method1();//实际调用的是子类中重写的方法
//      conn.method2();
//      conn.method3();}}

多态性练习:重写方法

package com.atguigu.exer;//考查多态的笔试题目:
public class InterviewTest1 {public static void main(String[] args) {Base1 base = new Sub1();base.add(1, 2, 3);//sub_1,调用的是重写的方法Sub1 s = (Sub1)base;//向下转型后就认为这是一个sub1类s.add(1,2,3);//sub_2,向下转型后确定的参数类型优先调用}
}class Base1 {public void add(int a, int... arr) {System.out.println("base1");}
}class Sub1 extends Base1 {//这个方法才是父类方法的重写,下面那个并不是public void add(int a, int[] arr) {System.out.println("sub_1");}public void add(int a, int b, int c) {System.out.println("sub_2");}}

向下转型

目的是为了调用子类中特有的属性和方法

功能少的不可能转化为功能多的,new的父类对象不能强转为子类对象

创建子类时会加载所有的父类,转型只能转为已经加载了的类,因为对象obj本质是woman类,加载woman类时就已经加载了person、object类

同一个父类的各个子类之间不可以互相转换

     //练习://问题一:编译时通过,运行时不通过//举例一:
//      Person p3 = new Woman();
//      Man m3 = (Man)p3;//举例二:
//      Person p4 = new Person();
//      Man m4 = (Man)p4;//问题二:编译通过,运行时也通过
//      Object obj = new Woman();
//      Person p = (Person)obj;//问题三:编译不通过
//      Man m5 = new Woman();//string和Date没有关系
//      String str = new Date();//编译时通过,运行时过不了
//      Object o = new Date();
//      String str1 = (String)o;

object类的使用

clone()方法的返回值类型是object,在复制的时候需要考虑是否需要强转为所需要的类型,克隆的对象和前对象的地址不同

finalize方法:在垃圾回收器之前会自动调用的一个方法

getClass():获取当前对象的类

==与equals()

一、回顾 == 的使用:

  • == :运算符
    1. 可以使用在基本数据类型变量和引用数据类型变量中
    1. 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)
  • 如果比较的是引用数据类型变量:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
  • 补充: == 符号使用时,必须保证符号左右两边的变量类型一致。
  • 二、equals()方法的使用:
    1. 是一个方法,而非运算符
    1. 只能适用于引用数据类型
    1. Object类中equals()的定义:
  • public boolean equals(Object obj) {
    return (this == obj);
    }
  • 说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
    1. 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
    1. 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写.
  • 重写的原则:比较两个对象的实体内容是否相同.

equals()方法重写思路:
1、先判断地址是否相等
2、判断是否是需要判断的类
若是的话,先进行强转,接着再比较各个属性值是否相等

开发中可以自动生成

单元测试方法

  • Java中的JUnit单元测试
  • 步骤:
  • 1.选中当前工程 - 右键选择:build path - add libraries - JUnit 4 - 下一步
  • 2.创建Java类,进行单元测试。
  • 此时的Java类要求:① 此类是public的 ②此类提供公共的无参的构造器
  • 3.此类中声明单元测试方法。
  • 此时的单元测试方法:方法的权限是public,没有返回值,没有形参
  • 4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
  • 5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
  • 6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
  • (详细的步骤如上,也可以直接在符合要求的类里面写上@Test和要测试的类,报错的时候直接点击解决办法就会一步到位解决了)
  • 说明:
  • 1.如果执行结果没有任何异常:绿条
  • 2.如果执行结果出现异常:红条

Junit不用new对象就能用属性了
在Junit里面可以选中不同的方法单独进行测试
在实际开发当中可以写完一个功能就在测试类里面写一个测试方法
注意:自己在造类的时候避免使用Test名字

包装类

基本数据类型——包装类

注意在使用new Integer()时候,括号里面可以放整数,也可以放字符串,但是字符串只能全是数字,不然会报错

         int num1 = 10;
//      System.out.println(num1.toString());Integer in1 = new Integer(num1);System.out.println(in1.toString());Integer in2 = new Integer("123");System.out.println(in2.toString());//报异常
//      Integer in3 = new Integer("123abc");
//      System.out.println(in3.toString());

对于布尔型
只要是true,不管大小写,都输出true,其他的输出false

     Boolean b1 = new Boolean(true);//()里面可以直接放true,也可以放string类型的Boolean b2 = new Boolean("TrUe");//输出trueSystem.out.println(b2);Boolean b3 = new Boolean("true123");System.out.println(b3);//false

布尔类型的包装类的默认值是null

基本数据类型只需要记住以下转换就可以
自动拆箱与自动装箱

 /** JDK 5.0 新特性:自动装箱 与自动拆箱*/@Testpublic void test3(){//      int num1 = 10;
//      //基本数据类型-->包装类的对象
//      method(num1);//自动装箱:基本数据类型 --->包装类int num2 = 10;Integer in1 = num2;//自动装箱boolean b1 = true;Boolean b2 = b1;//自动装箱//自动拆箱:包装类--->基本数据类型System.out.println(in1.toString());int num3 = in1;//自动拆箱}public void method(Object obj){System.out.println(obj);}

基本数据类型、包装类——string类

记住以下两种方法就ok,各个方法之间的效率差别不大
前两者转换为string类:valueOf(3.4f)
string类转换为前两者:parseXxx(string)

面试题

 @Testpublic void test3() {Integer i = new Integer(1);Integer j = new Integer(1);System.out.println(i == j);//false//Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在//-128~127范围内时,可以直接使用数组中的元素,不用再去new了。目的:提高效率Integer m = 1;Integer n = 1;System.out.println(m == n);//trueInteger x = 128;//相当于new了一个Integer对象Integer y = 128;//相当于new了一个Integer对象System.out.println(x == y);//false}

和String的常量池一样,基本数据类型也有常量池,取值是-128到127,所以引用的话地址相同,但是超过这个范围则是在堆里new一个了,另外浮点型不在常量池中

创建抽象类的匿名子类对象

package com.atguigu.java;
/** abstract关键字的使用* 1.abstract:抽象的* 2.abstract可以用来修饰的结构:类、方法* * 3. abstract修饰类:抽象类*       > 此类不能实例化*      > 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)*      > 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作* * * 4. abstract修饰方法:抽象方法*         > 抽象方法只有方法的声明,没有方法体*      > 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。*      > 若子类重写了父类中的所有的抽象方法后,此子类方可实例化*        若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰*/
public class AbstractTest {public static void main(String[] args) {//一旦Person类抽象了,就不可实例化
//      Person p1 = new Person();
//      p1.eat();}
}abstract class Creature{public abstract void breath();
}abstract class Person extends Creature{String name;int age;public Person(){}public Person(String name,int age){this.name = name;this.age = age;}//不是抽象方法:
//  public void eat(){//
//  }//抽象方法public abstract void eat();public void walk(){System.out.println("人走路");}}class Student extends Person{public Student(String name,int age){super(name,age);}public Student(){}public void eat(){System.out.println("学生多吃有营养的食物");}@Overridepublic void breath() {System.out.println("学生应该呼吸新鲜的没有雾霾的空气");}
}
package com.atguigu.java;
/** 抽象类的匿名子类* */
public class PersonTest {public static void main(String[] args) {method(new Student());//匿名对象Worker worker = new Worker();method1(worker);//非匿名的类非匿名的对象method1(new Worker());//非匿名的类匿名的对象  System.out.println("********************");   //创建了一匿名子类的对象:p//这个子类没有什么实际含义,就是想用里面的抽象方法,//所以就不显式定义子类了,是一种简化的写法/** 类person为抽象类,正常抽象类是无法实例化的,* 但如下用法相当于给person创建了一个临时子类,* 并声明出person类中的方法此时相当于给Person类创建了一个匿名子类,* 子类的实例化对象叫做p*/Person p = new Person(){@Overridepublic void eat() {System.out.println("吃东西");}@Overridepublic void breath() {System.out.println("好好呼吸");}};method1(p);System.out.println("********************");//创建匿名子类的匿名对象method1(new Person(){@Overridepublic void eat() {System.out.println("吃好吃东西");}@Overridepublic void breath() {System.out.println("好好呼吸新鲜空气");}});}public static void method1(Person p){p.eat();p.breath();}public static void method(Student s){}
}class Worker extends Person{@Overridepublic void eat() {}@Overridepublic void breath() {}}

创建接口匿名实现类的对象

匿名类就是把定义拉到函数内,匿名对象就是直接new不创建引用

package com.atguigu.java1;
/** 接口的使用* 1.接口使用上也满足多态性* 2.接口,实际上就是定义了一种规范* 3.开发中,体会面向接口编程!* */
public class USBTest {public static void main(String[] args) {Computer com = new Computer();//1.创建了接口的非匿名实现类的非匿名对象Flash flash = new Flash();com.transferData(flash);//2. 创建了接口的非匿名实现类的匿名对象com.transferData(new Printer());//3. 创建了接口的匿名实现类的非匿名对象USB phone = new USB(){@Overridepublic void start() {System.out.println("手机开始工作");}@Overridepublic void stop() {System.out.println("手机结束工作");}};com.transferData(phone);//4. 创建了接口的匿名实现类的匿名对象com.transferData(new USB(){@Overridepublic void start() {System.out.println("mp3开始工作");}@Overridepublic void stop() {System.out.println("mp3结束工作");}});}
}class Computer{public void transferData(USB usb){//USB usb = new Flash();usb.start();System.out.println("具体传输数据的细节");usb.stop();}}interface USB{//常量:定义了长、宽、最大最小的传输速度等void start();void stop();}class Flash implements USB{@Overridepublic void start() {System.out.println("U盘开启工作");}@Overridepublic void stop() {System.out.println("U盘结束工作");}}class Printer implements USB{@Overridepublic void start() {System.out.println("打印机开启工作");}@Overridepublic void stop() {System.out.println("打印机结束工作");}}

高级编程部分

多线程

有共享数据才会出现线程安全的问题
sleep函数会增加出现线程安全问题的概率
sleep不会释放锁
wait执行会释放锁
notify是把阻塞的线程唤醒,wait才是释放锁
异步并行,同步串行

p455



如果在name的地方又重新new了string类型的话又要在堆空间重新创建两个空间,此时的==比较结果应该是false

集合

set相关面试题

package com.atguigu.exer;import org.junit.Test;import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;/*** @author shkstart* @create 2019 上午 9:36*/
public class CollectionTest {@Testpublic void test1(){Collection coll = new ArrayList();coll.add(123);coll.add(456);coll.add(343);coll.add(343);coll.forEach(System.out::println);}//练习:在List内去除重复数字值,要求尽量简单public static List duplicateList(List list) {HashSet set = new HashSet();set.addAll(list);return new ArrayList(set);}@Testpublic void test2(){List list = new ArrayList();list.add(new Integer(1));list.add(new Integer(2));list.add(new Integer(2));list.add(new Integer(4));list.add(new Integer(4));List list2 = duplicateList(list);for (Object integer : list2) {System.out.println(integer);}}@Testpublic void test3(){HashSet set = new HashSet();Person p1 = new Person(1001,"AA");Person p2 = new Person(1002,"BB");set.add(p1);set.add(p2);System.out.println(set);p1.name = "CC";set.remove(p1);System.out.println(set);set.add(new Person(1001,"CC"));System.out.println(set);set.add(new Person(1001,"AA"));System.out.println(set);}}



存储的时候才会按照属性的hash值去存,后来要是属性改了,当前hash值不会改,但是调用remove方法的hash值会是是新的属性对应的hash值,那么有大概率找不到原来的位置,所以就没办法remove掉p1,p1放的位置是根据原始的p1的哈希值算出来进行放置的,而后续加的(1001,CC)算出来的哈希值和刚开始的p1算出来的不一样,因此会放在新的位置。第四个加进去的时候会触发equals函数,一个是AA,一个是CC,所以内容不一样,以链表的形式进行存储。

remove方法是比较的哈希值

反射

最常用的是第三种方法,第一种在编译的时候就必须得确认是哪种类型的对象,第三种在运行的时候才去确定是哪种对象

【JavaSE学习笔记】相关推荐

  1. JavaSE学习笔记(持续更新)

    这里写目录标题 JavaSE学习笔记(持续更新) Java跨平台原理与核心机制 1.跨平台原理: 2.两种核心机制: JDK11的安装流程 Java程序开发的三个步骤(无编辑器版) Eclipse安装 ...

  2. 重拾JavaSE学习笔记

    重拾JavaSE学习笔记 1.常用DOS命令 2.了解Java 2.1 .java特性 2.2.JDK .JRE.JVM 2.3.java的加载和执行 3.开发环境搭建 3.1.安装jdk 3.2.配 ...

  3. javaSE学习笔记01 入门篇

    javaSE学习笔记01 入门篇 java语言概述 Java背景知识 java是 美国 sun 公司 在1995年推出的一门计算机高级编程语言. java早期称为Oak(橡树),后期改名为Java. ...

  4. 我的javaSE学习笔记

    layout: post title: "我的JAVASE自学笔记" date: 2019-05-18 20:23:25 +0800 我的JAVASE自学笔记 作者:吴甜甜 个人博 ...

  5. JavaSE学习笔记-Day1

    笔者是一名大二在读本科生,最近闲着无聊重拾起Java这门语言,看了些许教学视频后居然还觉得挺有意思,"情不知所起,一往而深".于是决心认真学习这门语言!由于身居科班,自然不是零基础 ...

  6. JavaSE学习笔记(一)基础知识

    本章包含内容有: java环境配置.注释.标识符.数据类型.类型转换.变量.常量.运算符.包机制.顺序结构.选择结构.循环结构.方法的定义和调用.命令行传参.可变参数. 点击这里查看更多JavaSE的 ...

  7. javaSE学习笔记——第十四天正则表达式、Math类、System类、Data类、Calendar类等

    javaSE学习第十四天 java知识 正则表达式的概述和简单使用 A:正则表达式 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. 作用:比如 ...

  8. javaSE学习笔记——第四天循环结构、方法等

    javaSE学习第四天 java知识 循环结构的分类 for,while,do-while 循环结构for语句的格式: for(初始化表达式;条件表达式;循环后的操作表达式) {循环体;} for语句 ...

  9. 刘意JavaSE 学习笔记——总纲

    开始学习JavaSE了,记录下自己学习的进程. 学习大纲 1 开发环境配置 day01 配置 2 基础语法(基本差不多,看一下就好) day02 命名规则,进制转换 day03 运算符,if语句 da ...

最新文章

  1. servlet-------------jsp 地址栏变化
  2. MySQL sysdate-5_mysql sysdate 1
  3. 华为、阿里员工跳槽至微软受抵制,微软当事人称:只是玩梗
  4. python递归详解_打破递归栈的深度限制: 解析一种Python尾递归优化的方法
  5. iPhonexr安兔兔html5测试,给大家科普下iphonexr苹果手机安兔兔跑分多少分
  6. 【算法入门】动态图展示 6 个常用的数据结构,一目了然!
  7. ffmpeg 时间戳
  8. Thrift源码学习二——Server层
  9. mysql5.6.38占用内存过大问题解决
  10. 242.有效的字母异位词
  11. Pixhawk更换GPS协议 由默认ublox更换为NMEA GPGGA格式
  12. jspdf打印、pdf打印
  13. patch 和 put 方法区别
  14. 最短路问题之单源最短路-Dijkstra算法
  15. 我的项目开发经验积累总结
  16. Cisco Firepower FTD HA 配置文档
  17. Codeforces Round #451 (Div. 2)
  18. 【网络进阶】网络问题排查实例集锦(实战经验分享)
  19. python(28): 连接oracle环境离线安装及报错解决87,193
  20. 前端HTML中的怪异盒模型

热门文章

  1. 食神在命学里边是非常重要的。
  2. oracle数据库市场占有,Oracle数据库的高市场占有率
  3. php9宫格抽奖程序_PHP抽奖算法程序代码分享
  4. 武汉计算机985211大学有哪些,武汉985211大学有哪些
  5. 中国石油大学远程教育《应急救援概论》第二阶段在线作业
  6. 每天一道大厂SQL题【Day17】腾讯外包(微信相关)真题实战(二)
  7. win10永久关闭实时保护
  8. 文字检测识别技术的未来发展趋势和面临的选择
  9. eclipse中的中文乱码
  10. 腾讯云服务器没法远程控制,腾讯云服务器远程登录被拒绝