<meta charset="utf-8">
1.继承相关
public class Fu {
public int num = 10;
public Fu() {
System.out.println("Fu");
}
}
public class Zi extends Fu{
public int num = 20;
public Zi() {
System.out.println("Zi");
}
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
public class ExtendTest {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
2.jdk和jre有什么区别
JRE: Java Runtime Environment
JDK:Java Development Kit
JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。
JDK顾名思义是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。
3.Overload和Override的区别, Overload的方法是否可以改变返回值的类型
答:方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型
构造器Constructor是否可被override
答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading
4、 == 和 equals的区别
- "== " 基本数据类型是比较两个对象的内容(数值和数值类型)
int i = 2;
int k = 2;
char m = '2';
System.out.println(i == k); // true
System.out.println(m == k); // false
-
引用数据类型中 == 和 equals 比较的都是两个对象的地址值, 如果重写了 equals 方法比较的是两个对象的内容是否一致
Object obj1 = new Object();
Object obj2 = new Object();
// 都是比较的地址值
System.out.println(obj1.equals(obj2)); // false
System.out.println(obj1==obj2); // false
String 、Interger等类对equals进行了重写, 实际比较的是两个对象的内容是否一致
String a = new String("abcd");
String b = new String("abcd");
// abcd 放在常量池中
String c = "abcd";
String d = "abcd";
if (a == b){ // false
// 不是同一个对象
System.out.println("a==b");
}
if (a.equals(b)){
// true String 重写了equals
System.out.println("a==b equals");
}
if (c == d){
// true 共享同一变量
System.out.println("c==d");
}
if (c.equals(d)){
System.out.println("c.equals(d)");
}
String 的重写
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
// 判断是否属于String类型
if (anObject instanceof String) {
// 强制转换为String类型
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
5.抢红包 (综合练习)
<meta charset="utf-8">
需求:群主发普通红包, 某群有多名成员, 群主给成员发普通红包,规则为
群主有一笔金额, 从群主的余额中扣除, 平均分成n等分, 让成员去领
-
成员领取红包之后,保存到成员余额中
分析:
定义User类
package com.neusoft.day09.redbag;
/**
* @author Eric Lee
* @date 2020/7/23 10:48
*/
public class User {
// 用户名
private String userName;
// 余额
private int leftMoney;
public User() {
}
public User(String userName, int leftMoney) {
this.userName = userName;
this.leftMoney = leftMoney;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getLeftMoney() {
return leftMoney;
}
public void setLeftMoney(int leftMoney) {
this.leftMoney = leftMoney;
}
public void show(){
System.out.println("用户" + userName + "\t"+"余额为" + leftMoney + "元" );
}
}
群主类
package com.neusoft.day09.redbag;
import java.util.ArrayList;
/**
* @author Eric Lee
* @date 2020/7/23 10:52
*/
public class Manager extends User {
public Manager() {
}
public Manager(String userName, int leftMoney) {
super(userName, leftMoney);
}
// 发红包
public ArrayList<Integer> send(int totalMoney, int count){
ArrayList<Integer> redList = new ArrayList<>();
int leftMoney = super.getLeftMoney();
// 判断
if(totalMoney > leftMoney){
System.out.println("余额不足");
}
// 扣钱
super.setLeftMoney(leftMoney-totalMoney);
// 每个人发的钱
int avg = totalMoney/count;
// 除不开余出来的钱
int mod = totalMoney%count;
for (int i = 0; i <count-1 ; i++) {
redList.add(avg);
}
int last = avg+mod;
redList.add(last);
return redList;
}
}
成员类
package com.neusoft.day09.redbag;
import java.util.ArrayList;
import java.util.Random;
/**
* @author Eric Lee
* @date 2020/7/23 10:54
*/
public class Member extends User {
public Member() {
}
public Member(String userName, int leftMoney) {
super(userName, leftMoney);
}
//收红包
public void receive( ArrayList<Integer> list){
Random random = new Random();
int index = random.nextInt(list.size());
// Integer money = list.get(index);
// 收完之后删除
Integer removeMoney = list.remove(index);
// 更新余额
int leftMoney = super.getLeftMoney();
int updateMoney = leftMoney +removeMoney;
super.setLeftMoney(updateMoney);
}
}
测试类
package com.neusoft.day09.redbag;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author Eric Lee
* @date 2020/7/23 10:54
*/
public class Test {
public static void main(String[] args) {
Manager manager = new Manager("群主", 200);
Member one = new Member("成员A", 0);
Member two = new Member("成员B", 0);
Member three = new Member("成员C", 0);
manager.show();
one.show();
two.show();
three.show();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入金额");
int money = scanner.nextInt();
System.out.println("请输入发几个包");
int count = scanner.nextInt();
// 调用发红包
ArrayList<Integer> redList = manager.send(money, count);
// 调用收红包
one.receive(redList);
two.receive(redList);
three.receive(redList);
manager.show();
one.show();
two.show();
three.show();
}
}
效果
String类
<meta charset="utf-8">
请写出如下的输出结果
public class Father {
int x = 1;
public Father() {
System.out.println("Father");
}
public Father(String s) {
System.out.println("Father" + s);
}
}
public class Son extends Father{
int x = 2;
public Son() {
System.out.println("Son");
}
public Son(String s) {
System.out.println("Son" + s);
}
}
public class Test {
public static void main(String[] args) {
Son f = new Son();
System.out.println(f.x);
}
}
2. 请写出如下的输出结果
public class Father {
int x = 1;
public Father() {
System.out.println("Father");
}
public Father(String s) {
System.out.println("Father" + s);
}
}
public class Son extends Father{
int x = 2;
public Son() {
System.out.println("Son");
}
public Son(String s) {
System.out.println("Son" + s);
}
}
public class Test {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.x);
}
}
3. 请写出如下的输出结果
public class Father {
int x = 1;
public Father() {
System.out.println("Father");
}
public Father(String s) {
System.out.println("Father" + s);
}
}
public class Son extends Father{
int x = 2;
public Son() {
System.out.println("Son");
}
public Son(String s) {
System.out.println("Son" + s);
}
}
public class Test {
public static void main(String[] args) {
Father f = new Son("hello");
System.out.println(f.x);
}
}
总结:只要是new子类,无论是调用子类的有参构造还是无参构造都会执行父类的无参构造。当子类和父类有同一个变量名字的变量时,如果是使用了多态则调用的是父类的变量。否则调用的是子类的变量。
补充:执行顺序,静态块>构造语句块>函数块
4.作用域public,private,protected,以及不写时的区别
5.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)
匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现
6. &和&&的区别
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)
7.Math.round(11.5)等於多少? Math.round(-11.5)等於多少
Math.round(11.5)==12;Math.round(-11.5)==-11;round方法返回与参数最接近的长整数,参数加1/2后求其floor
8. short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错
答:short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)short s1 = 1; s1 += 1;(可以正确编译)
9. 数组有没有length()这个方法? String有没有length()这个方法
答:数组没有length()这个方法,有length的属性。String有有length()这个方法
10. Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型
答:方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型
11.abstract class和interface有什么区别
答:声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口
12. 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承实体类,但前提是实体类必须有明确的构造函数
13. 构造器Constructor是否可被override
答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading
14.是否可以继承String类
答:String类是final类故不可以继承
15. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递
答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的
16.char型变量中能不能存贮一个中文汉字?为什么?
答:是能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的
17. 面向对象的特征有哪些方面
1.继承:
继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
2.封装:
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
- 多态性:
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
18.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
答:可以。必须只有一个类名与文件名相同。
19. 是否可以从一个static方法内部发出对非static方法的调用?
答:不可以,如果其中包含对象的method();不能保证对象初始化.
20. 在JAVA中,如何跳出当前的多重嵌套循环?
答:用break; return 方法。
21. this关键字的作用
答:1、this调用当前属性:其主要作用是当需要给类中的数据进行初始化时,可以通过this来进行赋值,而不用随便定义一个变量来进行赋值,更有利于代码的阅读与理解;
2、this调用方法(普通方法、构造方法):其中普通方法与构造方法的区别是构造方法在创建后只能掉用一次,用来初始化数据,而普通方法在创建后可以调用多次, 注:对this调用必须是构造方法中的第一个语句,否则便会出错,当然也不能在普通方法中调用构造方法,最为重要的是,使用this调用不能形成循环,即不能形成递归调用而没有出口;
3、this表示当前方法,在整个过程中,this的定义没有变,只要有某一个对象调用本类中的方法,此时this就表示当前执行的对象。
22..谈一下HashMap的特性?
答:1.HashMap存储键值对实现快速存取,允许为null。key值不可重复,若key值重复则覆盖。
2.非同步,线程不安全。
3.底层是hash表,不保证有序(比如插入的顺序)
23.死锁
答:https://blog.csdn.net/hd12370/article/details/82814348
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
产生死锁的原因可归结为如下两点:
竞争资源
系统中的资源可以分为两类:
1.可剥夺资源,是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺,CPU和主存均属于可剥夺性资源;
2.另一类资源是不可剥夺资源,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。
- 产生死锁中的竞争资源之一指的是竞争不可剥夺资源(例如:系统中只有一台打印机,可供进程P1使用,假定P1已占用了打印机,若P2继续要求打印机打印将阻塞)
- 产生死锁中的竞争资源另外一种资源指的是竞争临时资源(临时资源包括硬件中断、信号、消息、缓冲区内的消息等),通常消息通信顺序进行不当,则会产生死锁
进程间推进顺序非法
- 若P1保持了资源R1,P2保持了资源R2,系统处于不安全状态,因为这两个进程再向前推进,便可能发生死锁
24.单线程与多线程的区别
答:1、多线程间并行,是一个进程中的多个执行流,可理解为将一个大任务拆分出的多个子任务。
2、多线程适用场景
1)存在需要等待IO、网络或其他外部资源的任务。当前等待其他资源却依旧占用CPU的线程可让出CPU,让其他线程执行,大大提高了程序效率,充分利用了CPU资源。
2)存在长时间占用CPU的任务。CPU以时间片为单位分配给各个线程,一个周期内各个线程都可以得到执行,而非卡在一个线程。而且多线程意味着分配到的CPU时间片也更多。
3、多线程弊端
1)访问共享资源时要小心,需要更多的锁资源,同步更加复杂。
2)内存占用更多,资源开销更大。
3)需要额外的线程调度和管理。如需要CPU时间来跟踪线程。
25.什么是进程?
当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。
26.什么是线程?
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
27.什么是多线程?
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务,它是异步的。
多线程的好处:
可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。
多线程的不利方面:
线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
多线程需要协调和管理,所以需要CPU时间跟踪线程;
线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
线程太多会导致控制太复杂,最终可能造成很多Bug;
28.JDBC操作数据库的步骤:
- 注册数据库驱动
- 建立数据库连接
- 创建一个statement
- 执行sql语句
- 处理结果集
- 关闭数据库连接
29.在mabitys里#和$的区别:
mybatis中的#和$的区别
1.#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2."美元"将传入的数据直接显示生成在sql中。如:order by $user_id,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
3.#方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#,默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串使用。比如,像ORDER BY,你可以这样来使用;
30.Map集合遍历的方法:
1.通过Map.keySet遍历key和value
map.keySet()返回的是所有key的值
map.get(in)得到每个key对应value的值
2.通过Map.entrySet使用iterator遍历key和value
3.通过Map.entrySet遍历key和value
map.entrySet() 返回此映射中包含的映射关系的 Set视图。
4.通过Map.values()遍历所有的value,但不能遍历key
31.表单和视图的区别和联系:
- 区别:
1、视图是已经编1653译好的sql语句。而表不是
2、视图没有实际的物理记录。而表有。
3、表是内容,视图是窗口
4、表只用物理空间而视图不占用物理空间,视图只是逻辑概念的存在,表可以及时四对它进行修改,但视图只能有创建的语句来修改
5、表是内模式,试图是外模式
6、视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些SQL语句的集合。从安全的角度说,视图可以不给用户接触数据表,从而不知道表结构。
7、表属于全局模式中的表,是实表;视图属于局部模式的表,是虚表。
8、视图的建立和删除只影响视图本身,不影响对应的基本表。 - 联系:
视图(view)是在基本表之上建立的表,它的结构(即所定义的列)和内容(即所有数据行)都来自基本表,它依据基本表存在而存在。一个视图可以对应一个基本表,也可以对应多个基本表。视图是基本表的抽象和在逻辑意义上建立的新关系
32.java项目前后台怎么交互详解
- 1、前台发送数据到服务端,以及接受后台数据:
(1)使用<form>表单发送同步请求
(2)使用ajax发送异步请求,发送的数据为json对象 - 2、服务端后台接受数据
(1)继承HttpServlet类,使用request.getParameter("name")方法获取请求参数
(2)使用注解@RequestParam直接获取
(3)使用@ResponseBody注解来解析json对象 - 3、服务端给客户端返回数据
(1)可以继承HttpServlet类,获取请求参数,同时将数据通过流的形式发送到前台。返回的可以是字符串,也可以是json对象。
(2)返回页面,Controller中方法返回JSON对象,如果需要携带数据通过ModelAndView(相当于一个Map)传递到view, view中使用jstl的EL表达式来绑定ModelAndView带来的数据。
(3)返回Json对象,利用@ResponseBody来实现。spring MVC自动将java对象转化成了json对象传回了客户端,返回对象可以是Pojo也可以是List直接操作Response自己实现想要的效果。
(4)将对象(或数组)转换成json对象(或json数组),发送到前台
33.Mysql建表语句:
栗子:
CREATE TABLE <表名> ([表定义选项])[表选项][分区选项];
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
name VARCHAR(200) COMMENT '姓名',
age int COMMENT '年龄'
) COMMENT='学生信息'
34.数据库改变字段名称语句:
1、在oracle数据库中: ALTER TABLE 表名 RENAME COLUMN 列名 TO 新列名。
2、在sqlserver数据库中:exec sp_rename '[表名].[列名]‘,’[表名].[新列名]'。
3、在mysql数据库中:ALTER TABLE 表名 CHANGE 列名 新列名 列类型。
35.数据库增删改查
一、增:有两种方法
1.使用insert插入单行数据:
语法:insert [into] <表名> [列名] values <列值>
例:insert into Strdents (姓名,性别,出生日期) values ('张三','男','1983/6/15')
注意:如果省略表名,将依次插入所有列
2.使用insert,select语句将现有表中的 数据添加到已有的新表中
语法:insert into <已有的新表> <列名> select <原表列名> from <原表名>
例:insert into addressList ('姓名','地址','电子邮件')select name,address,email
from Strdents
二、删:有2中方法
1.使用delete删除数据某些数据
语法:delete from <表名> [where <删除条件>]
例:delete from a where name='张三'(删除表a中列值为张三的行)
注意:删除整行不是删除单个字段,所以在delete后面不能出现字段名
2.使用truncate table 删除整个表的数据
语法:truncate table <表名>
例:truncate table addressList
注意:删除表的所有行,但表的结构、列、约束、索引等不会被删除;不能
用于有外建约束引用的表
三、改 使用update更新修改数据
语法:update <表名> set <列名=更新值> [where <更新条件>]
例:update addressList set 年龄=18 where 姓名='张三'
注意:set后面可以紧随多个数据列的更新值(非数字要引号);where子句是可选的(非数字要引号),用来限制条件,如果不选则整个表的所有行都被更新
四、查
语法:select <列名> from <表名> [where <查询条件表达试>] [order by <排序的列
名>[asc或desc]]
1).查询所有数据行和列
例:select * from a
说明:查询a表中所有行和
2).查询部分行列--条件查询
例:select i,j,k from a where f=5
说明:查询表a中f=5的所有行,并显示i,j,k3列
3).在查询中使用AS更改列名
例:select name as 姓名 from a where gender='男'
说明:查询a表中性别为男的所有行,显示name列,并将name列改名为(姓名)显示
4).查询空行
例:select name from a where email is null
说明:查询表a中email为空的所有行,并显示name列;SQL语句中用is null或者is not null
来判断是否为空行
5).在查询中使用常量
例:select name '北京' as 地址 from a
说明:查询表a,显示name列,并添加地址列,其列值都为'北京'
6).查询返回限制行数(关键字:top )
例1:select top 6 name from a
说明:查询表a,显示列name的前6行,top为关键字(oracle 中没有top关键字
用rownum替代)
select * from a where rownum<6
7).查询排序(关键字:order by , asc , desc)
例:select name
from a
where grade>=60
order by desc
说明:查询表中成绩大于等于60的所有行,并按降序显示name列;默认为ASC升序
36.怎么生成一个随机数
Java中提供了一个获取随机数的一个类(Math),生成随机数要使用Math类下的方法:random()方法的返回值是[0.0 - 1.0)
Math:此类在java.lang包下,jvm会自动导入,所以无需import导包;
1.获取上述范围内的随机数:
//获取上述范围内的随机数
double d = Math.random();
System.out.print(d);
注:上述式子若写成下面这样,那么i的值只会是0;因为Math.random()生成的随机数范围为[0.0 - 1.0),此时无论随机数为何值转为int时值只会是0
int i = (int)(Math.random());
2.获取一个1~100之间的随机数(int型)
//获取一个1~100之间的随机数(int型)
int num = (int)(Math.random()*100+1);
System.out.print(num);
3.获取一个任意范围(n~m)之间的随机整数(int型)
//获取一个任意范围(n~m)之间的随机整数(int型)
int num = (int)(Math.random()*(m-n+1)+m);
Syste.out.print(num);
注:一定要大数减去小数
37.SpringBoot常用注解
1.@SpringBootApplication:包含@Configuration、@EnableAutoConfiguration、@ComponentScan通常用在主类上。
2、@Repository:用于标注数据访问组件,即DAO组件。
3、@Service:用于标注业务层组件。
4、@RestController:用于标注控制层组件(如struts中的action),包含@Controller和@ResponseBody。
5、@ResponseBody:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析,为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
6、@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
7、@ComponentScan:组件扫描。相当于,如果扫描到有@Component @Controller @Service等这些注解的类,则把这些类注册为bean。
8、@Configuration:指出该类是 Bean 配置的信息源,相当于XML中的,一般加在主类上。
9、@Bean:相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。
10、@EnableAutoConfiguration:让 Spring Boot 根据应用所声明的依赖来对 Spring 框架进行自动配置,一般加在主类上。
11、@AutoWired:byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。
12、@Qualifier当有多个同一类型的Bean时,可以用@Qualifier("name")来指定。与@Autowired配合使用。
13、@Resource(name="name",type="type"):没有括号内内容的话,默认byName。与@Autowired干类似的事。
14、@RequestMapping:RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:
(1)params:指定request中必须包含某些参数值是,才让该方法处理;
(2)headers:指定request中必须包含某些指定的header值,才能让该方法处理请求
(3)value:指定请求的实际地址,指定的地址可以是URI Template 模式;
(4)method:指定请求的method类型, GET、POST、PUT、DELETE等;
(5)consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
(6)produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
15、@RequestParam:用在方法的参数前面。
@RequestParam String a =request.getParameter("a")。
16、@PathVariable:路径变量。参数与大括号里的名字一样要相同。
RequestMapping("user/get/mac/{macAddress}")
public String getByMacAddress(@PathVariable String macAddress){
//do something;
}
17、@Profiles:Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定的环境下生效。任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。
@Configuration
@Profile("prod")
public class ProductionConfiguration { // ...}
18、@ConfigurationProperties:Spring Boot将尝试校验外部的配置,默认使用JSR-303(如果在classpath路径中)。你可以轻松的为你的@ConfigurationProperties类添加JSR-303 javax.validation约束注解:
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
@NotNullprivate InetAddress remoteAddress;
// ... getters and setters
}
全局异常处理:@ControllerAdvice包含@Component,可以被扫描到。
统一处理异常:@ExceptionHandler(Exception.class):
38.怎么防止SQL注入
- 代码层防止sql注入攻击的最佳方案就是sql预编译;
- 确认每种数据的类型,比如是数字,数据库则必须使用int类型来存储;
- 规定数据长度,能在一定程度上防止sql注入;
- 严格限制数据库权限,能最大程度减少sql注入的危害;
- 避免直接响应一些sql异常信息,sql发生异常后,自定义异常进行响;
- 过滤参数中含有的一些数据库关键词。
39.Spring依赖注入和控制反转:
40.怎么理解定时器?
41.什么是回滚?
42.怎么把开发好的APP发布在网上?
43.关于Swagger注解-@ApiModel 和 @ApiModelProperty的理解:
@ApiModel
使用场景
在实体类上边使用,标记类时swagger的解析类
概述
提供有关swagger模型的其它信息,类将在操作中用作类型时自动内省
属性
@ApiModelProperty
使用场景
使用在被 @ApiModel 注解的模型类的属性上
概述
添加和操作模型属性的数据
属性
44.三目运算符:在三目运算符里面 "?" 是和 ":" 一起用的,例如:
boolean someCondition = true;
// 表示,当someCondition是true 的时候,把 "a" 赋值给 result;为false 的适合把 "b" 赋值给result
String result = someCondition ? "a" : "b" ;
45.在MySQL中可以使用IF()、IFNULL()、NULLIF()、ISNULL()函数进行流程的控制:
(1)、IF()函数的使用
IF(expr1,expr2,expr3),如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的值。
1| SELECT IF(TRUE, 'A','B'); --输出结果:A
2| SELECT IF(FALSE,'A','B'); --输出结果:B
(2)、IFNULL()函数的使用
IFNULL(expr1,expr2),如果expr1的值为null,则返回expr2的值,如果expr1的值不为null,则返回expr1的值。
1| SELECT IFNULL(NULL,'B'); -- 输出结果:B
2| SELECT IFNULL( 'HELLO', 'B'); -- 输出结果:HELLO
(3)、NULLIF()函数的使用
NULLIF(expr1,expr2),如果expr1=expr2成立,那么返回值为null,否则返回值为expr1的值。
1| SELECT NULLIF( 'A','A');--输出结果:null
2| SELECT NULLIF( 'A','B');--输出结果:A
(4)、ISNULL()函数的使用
ISNULL(expr),如果expr的值为null,则返回1,如果expr1的值不为null,则返回0。
1| SELECT ISNULL(NULL);--输出结果:1
2| SELECT ISNULL( 'HELLO');--输出结果:0
46.模糊查询
一般模糊查询语句如下:
SELECT 字段 FROM 表 WHERE 某字段 Like 条件
其中关于条件,SQL提供了四种匹配模式:
(1).% :表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示,比如 :
SELECT * FROM [user] WHERE u_name LIKE '%三%'; --将会把u_name为“张三”,“张猫三”、“三脚猫”,“唐三藏”等等有“三”的记录全找出来。
SELECT * FROM [user] WHERE u_name LIKE '%三%' AND u_name LIKE '%猫%'; --找出u_name中既有“三”又有“猫”的记录
SELECT * FROM [user] WHERE u_name LIKE '%三%猫%'; --虽然能搜索出“三脚猫”,但不能搜索出符合条件的“张猫三”。
(2)._ : 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句,比如
SELECT * FROM [user] WHERE u_name LIKE '_三_'; --只找出“唐三藏”这样u_name为三个字且中间一个字是“三”的;
SELECT * FROM [user] WHERE u_name LIKE '三__'; --只找出“三脚猫”这样name为三个字且第一个字是“三”的;
(3).[ ] :表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个,比如:
SELECT * FROM [user] WHERE u_name LIKE '[张李王]三'; --找出“张三”、“李三”、“王三”(而不是“张李王三”);
SELECT * FROM [user] WHERE u_name LIKE '老[1-9]'; --将找出“老1”、“老2”、……、“老9”(字符(01234、abcde之类的)则可略写为“0-4”、“a-e”);
(4).[^ ] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符,比如
SELECT * FROM [user] WHERE u_name LIKE '[^张李王]三'; --将找出不姓“张”、“李”、“王”的“赵三”、“孙三”等;
SELECT * FROM [user] WHERE u_name LIKE '老[^1-4]'; --将排除“老1”到“老4”,寻找“老5”、“老6”、……
47.JDK 8 用Stream对集合排序:在开发过程中,大多数的排序场景,我们都可以使用数据库的order by关键字就能够给数据进行排序,但是有些场景是需要获得数据后,需要通过某个对象的属性自定义排序,这个时候我们就可以使用jdk 8 的stream进行排序。
举个栗子:对List集合排序
首先,创建学生对象
public class Student{
private String name;
private Integer score;
private Integer age;
public Student(String name, Integer age, Integer score){
this.name = name;
this.age = age;
this.score = score;
}
//省略getter和setter
}
再根据学生成绩进行排序:
public static void main(String[] args){
List<Student> studentList = new ArrayList<>();
Student xiaoming = new Student();
studentList.add(new Student("小明",19,100));
studentList.add(new Student("小红",20,80));
studentList.add(new Student("小红",18,90));
//根据分数升序排序
/**
*需要注意的是,原来的数组是没有变化的,需要重新将排序后的数据集合进行toList()
*/
List<Student> sortedStudentASC = studentList.stream().sorted(Comparator.comparing(Student::getScore)).collet(Collectors.toList());
//降序排序
List<Student> sortedStudentDESC = studentList.stream().sorted(Comparator.comparing(Student::getScore).reserved()).collet(Collectors.toList());
sortedStudentASC.forEach(item -> System.out.println("name=" + item.getName+" age="+ item.getAge() + " score=" + item.getScore()));
sortedStudentDESC.forEach(item -> System.out.println("name=" + item.getName+" age="+ item.getAge() + " score=" + item.getScore()));
}
控制台输出:
升序排序:
name=小红 age=20 score=80
name=小李 age=18 score=90
name=小明 age=19 score=100
---------------------------
降序排序
name=小明 age=19 score=100
name=小李 age=18 score=90
name=小红 age=20 score=80