【面试题的归纳总结】面试题目的总结2

1.创建线程的方式与实现

有3种创建方式:1.继承thread类 2.实现runnable接口(工作常用) 3.Callable接口

继承Thread类

run():用于定义线程的执行体

①继承Thread类——>子类变成线程类

②重写Thread类的run()

③创建线程对象

④调用线程对象的start()

example

public class Dog  extends  Thread{ //1.继承Thread类
    private String name;
    public Dog(String name,String threadname) {
        super(threadname);//改变线程的名字
        this.name = name;
    }
    public void run(){ //2.重写Thread类的run方法
        for (int i = 0; i < 10; i++) {
            System.out.println("狗叫"+name);
        }
    }
}
psvm{//案例1:
       //线程对象,但不能复用,不能用于其他方面
       //缺点:线程任务和线程耦合
       //继承thread:用构造器改名字
       Dog dog=new Dog("大黄","线程1"); //3.创建线程对象
        dog.start();//执行多线程的方法
        //dog.run();//这样会变成单线程
        Dog dog2=new Dog("小白","线程2");
        dog2.start(); //4.调用线程对象的start()
        //单线程,只有dog执行完,才能执行此dog2
        //创建新线程:①实体类继承Thread,②重写run ③调用start()
        System.out.println("main方法结束");//前面报错,此语句仍然会执行<——其他线程报错,主线程仍能执行
}

实现Runnable接口(常用)

优点:

考虑解耦和扩展性

①实现Runnable接口,重写run()

②创建Thread类的对象

③将实现类的对象作为参数传递给Thread类的构造方法

④调用Thread类对象的start():a.开启线程 b.调用实现类的run()

example


public class Cat  implements  Runnable{  //1.实现接口
    private String name;
    public Cat(String name) {
        this.name = name;
    }
    @Override
    public void run() {  //2.实现runnable接口的run()
        for (int i = 0; i <4 ; i++) {
            System.out.println("cat howl:"+name+Thread.currentThread().getName());
        }
    }
}
psvm{
        //更加灵活,可以复用;考虑解耦和灵活性;健壮性,代码量
        //直接在注入普通对象时改变线程名字
       System.out.println(Thread.currentThread().getName());//获取主线程的名字
        Cat cat=new Cat("baibai");
        Cat cat1=new Cat("hhhhhhhh");
    //3.将实现类的对象作为参数传递给Thread类的构造方法
        Thread t1=new Thread(cat1,"线程2"); //直接修改线程的名字
        Thread t=new Thread(cat,"线程1");
        t.start(); //4.调用Thread类对象的start()
        t1.start();
}

实现Callable接口

重写call()方法,然后包装成java.util.concurrent.FutureTask, 再然后包装成Thread

Callable:有返回值的线程,能取消线程,可以判断线程是否执行完毕

● 借助FutureTask类来判断线程是否已经执行完毕或者取消线程执行

2.线程池的几种方式

1.newFixedThreadPool(固定长度线程)

定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程

2.newCachedThreadPool

可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制

3.newScheduledThreadPool

定长线程池,可执行周期性的任务

4.newSingleThreadExecutor

单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行

5.newSingleThreadScheduledExecutor

单线程可执行周期性任务的线程池

6.newWorkStealingPool
任务窃取线程池,不保证执行顺序,适合任务耗时差异较大。
线程池中有多个线程队列,有的线程队列中有大量的比较耗时的任务堆积,而有的线程队列却是空的,就存在有的线程处于饥饿状态,当一个线程处于饥饿状态时,它就会去其它的线程队列中窃取任务。解决饥饿导致的效率问题。
默认创建的并行 level 是 CPU 的核数。主线程结束,即使线程池有任务也会立即停止。

3.线程的生命周期

初始——就绪(调用start()后)——运行——消亡——有限期等待(通过yield()、sleep())——无限期等待(通过join())——阻塞

● 一个线程在调用start()前,一直处于创建状态
● 多条线程不一定有安全问题,除非进行共享资源的操作且是多行代码
在这里插入图片描述
在这里插入图片描述

● 创建(new)状态: 准备好了一个多线程的对象,即执行了new Thread(); 创建完成后就需要为线程分配内存
● 就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度
● 运行(running)状态: 执行run()方法
● 阻塞(blocked)状态:
● 死亡(terminated)状态: 线程销毁(正常执行完毕、发生异常或者被打断interrupt()都会导致线程终止)

start和run

start()

启动一个线程,线程之间是没有顺序的,是按CPU分配的时间片来回切换的

run():

普通的方法调用,虽然将代码封装到两个线程体中,可以看到线程中打印的线程名字都是main主线程,run()方法用于封装线程的代码,具体要启动一个线程来运行线程体中的代码(run()方法)还是通过start()方法来实现,调用run()方法就是一种顺序编程不是并发编程。

4.悲观锁 乐观锁

数据库中有悲观锁和乐观锁

悲观锁(Pessimistic Lock):

就是很悲观,每次去拿数据的时候都认为别人会修改。所以每次在拿数据的时候都会上锁。这样别人想拿数据就被挡住,直到悲观锁被释放,悲观锁中的共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程

数据库中的行锁,表锁,读锁(共享锁),写锁(排他锁),以及syncronized实现的锁

悲观并发控制实际上是“先取锁再访问”的保守策略

乐观锁(Optimistic Lock):

就是很乐观,每次去拿数据的时候都认为别人不会修改。所以不会上锁,但是如果想要更新数据,则会在更新前检查在读取至更新这段时间别人有没有修改过这个数据。如果修改过,则重新读取,再次尝试更新,循环上述步骤直到更新成功(当然也允许更新失败的线程放弃操作),乐观锁适用于多读的应用类型

4.1乐观锁的业务场景和实现方式

乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。

乐观锁用于读多写少的情况,即很少发生冲突的场景,这样可以省去锁的开销,增加系统的吞吐量。

乐观锁的适用场景有很多,典型的比如某成本系统,柜员要对一笔金额做修改,为了保证数据的准确性和实效性,使用悲观锁锁住某个数据后,再遇到其他需要修改数据的操作,那么此操作就无法完成金额的修改,对产品来说是灾难性的一刻,使用乐观锁的版本号机制能够解决这个问题

5.字节流和字符流的区别

输入与输出是对内存而言,读取与写入是对硬盘而言

io流按传输单位划分为字节流和字符流;都属于抽象类

在这里插入图片描述

5.1 Java中流类的超类主要由那些

在这里插入图片描述

5.2FileInputStream和FileOutputStream是什么

● 字节文件的输入输出流;
● 继承自父类InputStream、OutputStream;
● 拷贝文件操作的时候,经常用到的两个类。在处理小文件的时候,它们性能表现还不错,在大文件的时候,最好使用BufferedInputStream
(或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)
在这里插入图片描述

8.JDBC流程

天龙八部

  1. 导jar包
  2. 添加为库
  3. 注册驱动——
8com.mysql.cj.jdbc.Driver5com.mysql.jdbc.Driver 
 Class.forName("com.mysql.cj.jdbc.Driver");//工具类准备就绪
  1. 与数据库创建连接 地址(主机地址:端口号/数据库名);用户名;密码
 conn= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mytext","root","123456");

5.预执行sql语句:只是连接,还未执行
//执行修改语句,此处有漏洞

preparedStatement = conn.prepareStatement("UPDATE school set schName='黑龙江' where id=5; ");//修改语句
  1. 给问号占位符赋值
    ● ?占位符——>为了解决sql注入漏洞
preparedStatement.setInt(1,"数据库中的字段名");
preparedStatement.setString(2,"数据库中的字段名");
  1. 执行sql,并接收返回结果
 re= pr.executeQuery();
 int i=pr.executeUpdate();
  1. 关闭连接通道和 (先开后关)
    ● 关闭顺序:1.结果集 2.预执行对象 3.连接对象
try{
            if(re!=null){
                re.close();
            }
            if(pr!=null){
                pr.close();
            }
            if(connection!=null){
                connection.close();
            }
        }catch(Exception e){
            e.printStackTrace();
        }

9.讲一下三次握手四次挥手,为何是三次握手而不是两次

对话模型诠释三次,两次,四次握手场景
三次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天balabala……”

两次握手:
“喂,你听得到吗?”
“我听得到呀”“喂喂,你听得到吗?”
“草,我听得到呀!!!!”
“你TM能不能听到我讲话啊!!喂!”“……”

四次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,你能听到我吗?”
“……不想跟傻逼说话”

总结:三次刚刚好,二次达不到目的,四次多余。

原理简版

(其实是通过三次握手确认双方的发送接收都正常):
1.A向B发一个数据包(SYN)。
注:B知道A可以发送。
2.B收到数据包后,向A回一个数据包。(SYN+ACK)
注:A知道B可以接收和发送。
3.A收到数据包后,向B回一个数据包。(ACK)
注:B知道A可以接收。

为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

三次握手(深入理解)

第一次握手:
客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:
服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”

四次挥手

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
CP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

10.HTTP的结构

由请求报文和响应报文组成

一个HTTP请求报文由请求行、请求头、空行和请求数据4个部分组成

HTTP响应报文同样也分为状态行、消息报头、空行、响应正文

请求报文

请求行、请求头、空行和请求数据4个部分组成

请求行

由请求方法、请求URL(不包括域名)、HTTP协议版本组成

请求方法

默认使用get
在这里插入图片描述

HTTP协议版本

HTTP 1.0

支持GET、POST、HEAD三种HTTP请求方法。

HTTP1.0 每次请求都需要建立新的TCP连接,连接不能复用。

HTTP1.1

该版本默认采用持久连接,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以降低线路负载,提高传输速度。

HTTP1.1新增了:OPTIONS、PUT、DELETE、TRACE、CONNECT五种HTTP请求方

请求头部

求头部由关键字/值对组成,每行一对

User-Agent : 产生请求的浏览器类型
Accept : 客户端希望接受的数据类型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型
Content-Type:发送端发送的实体数据的数据类型。
比如,Content-Type:text/html(application/json)表示发送的是html类型。
Host : 请求的主机名,允许多个域名同处一个IP地址,即虚拟主机

空行

请求头之后是一个空行,通知服务器以下不再有请求头

请求数据

GET没有请求数据,POST有。

与请求数据相关的最常使用的请求头是 Content-Type 和 Content-Length

响应报文

HTTP响应报文同样也分为三部分,有状态行、首部行、实体

状态行

:HTTP响应报文的第一行

状态行包括三个字段:协议版本、状态码与原因短语

状态码:

由3位数字组成,第一个数字定义了响应的类别

● 1xx:
这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。
● 2xx:
这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
● 3xx:
这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。
● 4xx:
这类的状态码代表客户端类的错误
● 5xx:
服务器类的错误

HTTP状态码分为5种类型:

1、信息,服务器收到请求,需要请求者继续执行操作

2、成功,操作被成功接收并处理

3、重定向,需要进一步的操作以完成请求

4、客户端错误,请求包含语法错误或无法完成请求

5、服务器错误,服务器在处理请求过程中发生了错误

常见的响应状态码

200 OK 客户端请求成功,即处理成功,这是我们最想看到的状态码

400 Bad Request 客户端请求有语法错误,不能被服务器所理解

404 Not Found 请求资源不存在,一般是URL输入有误,或者网站资源被删除了

500 Internal Server Error 服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧

10.3 https和http的区别

● 无状态的意思是其数据包的发送、传输和接收都是相互独立的。
● 无连接的意思是指通信双方都不长久的维持对方的任何信息。
● SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持
在这里插入图片描述

10.4 https的实现原理

是以安全为目标的 HTTP 通道,是 HTTP 的安全版。HTTPS 的安全基础是 SSL。

SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。

SSL 协议可分为两层:SSL 记录协议(SSL Record Protocol),它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。

SSL 握手协议(SSL Handshake Protocol),它建立在 SSL 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

12 网络OSI七层模型有哪些,TCP是哪层

tcp位于运输层
在这里插入图片描述

14.Javaweb三大组件

servlet、过滤器、监听器
过滤器Filter:通用设置和权限认证
监听器Listener:监听域对象什么时候创建、什么时候销毁

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值