天天看点

知识点小结--20200807

2020年8月7号

1. Java面向对象编程的三大特性。

  • 封装

    封装是把一个对象属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供外界的访问方法,那这个类也没有什么意义

  • 继承

    继承是使用存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能。也可以用父类的功能,但不能选择性的继承父类,通过使用继承,我们能够非常方便的服用以前的代码。

    关于继承的三个点:

    • 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法,子类是无法访问的,只是拥有。
    • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
    • 子类可以用自己的方式实现父类的方法。
  • 多态

    所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用,用在编程时并不确定,而是在程序运行期间才确定的,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在有程序运行期间才能决定

    在Java中有两种形式可以实现多态:继承(多个子类对同一个方法的重写)和接口(实现接口并覆盖接口中的统一方法)

2.String StringBuffer和StringBuilder的区别? String为什么 是不可变的。

  • 可变性:

    简单来说,String类中使用final关键字修饰字符数组来保存字符串,private final char value[],所以String对象是不可变的

    (java9 之后改变成为bytep[]数组进行存储字符串)

    而StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串char[]value,但是没有用final关键字修饰,所以这两个是可变的。

  • 线程安全性

    String中的对象是不可变的,也就可以理解为常量,线程安全,而AbstractStringBuilder 是 StringBuilder 与 StringBuffer的公共父类,定义了一些字符串的基本操作,如:expandCapacity、append、append、insert、indexof等公共方法。

    StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

    StringBuilder并没有对方法进行加同步锁,所以非线程安全的

  • 性能

    每次对String类型进行改变的时候,都会生成一个新的String对象,然后将指针向新的String对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StringBuilder相比使用StringBuffer仅能获得10-15%左右的性能提升,但却要冒线程不安全的风险

    • 操作少量数据:适用String
    • 单线程操作字符串缓冲区下操作大量数据:适用StringBuilder
    • 多线程操作字符串缓冲区下操作大量数据:使用StringBuffer

3.==与equals的区别

  • = = 他的作用是判断两个对象的地址是不是相等。即:判断两个对象是不是同一个对象(基本数据= =比较的是值,引用数据类型= =比较的是内存地址)
  • equals():他的作用是判断两个对象是否相等,但是一般有两种使用情况:
    • 情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象是,等价于通过“==”比较这两个对象
    • 情况2:类覆盖了equals()方法。一般我们都覆盖equals()方法来比较两个对象是否相等,若相等,则返回true(认为这两个对象相等)
    • String中的equals方法是被重写过的,因为Objact的equals方法是比较的对象的内存地址,而String的equals方法比较的是两个对象的值
    • 当创建String类型的对象时,虚拟机在常量池中查找有没有已存在的值和要创建的值相同的对象,如果有则赋值给当前引用,如果没有则在常量池中重新创建一个String对象

4. 介绍hashCode与equals,为什么要有hashCode,他们的相关规定是什么。

  • Hashcode()

    Hashcode()的作用是获取哈希码,也成为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希列表中的索引位置。Hashcode()定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashcode()函数。

    散列表存储的是键值对,它的特点是:能根据“键”快速的检索出对应的“值”。着其中就利用到了散列码。(可以快速的找到需要的对象)

  • 为什么要有hashcode

    先从“HashSet如何检查重复为例子”说明为什么要有哈希码:当你把对象加入hashset时,它会先计算对象的哈希码来判断对象加入的位置,同时也会与该位置其他已经加入的对象的哈希码值进行比较,如果没有相符的哈希码,HashSet会假设对象没有重复出现。但是如果发现有相同的哈希码值的对象,这时候会调用equals()方法来检查哈希码相等的对象是否真的相同。如果两者相同,HashSet就不会让其他加入操作成功。如果不同的话,就会重新散列到其他位置。(这样做的好处是减少了equals的次数,提高了执行速度)

    可以看出,hashcode()的作用就是获取哈希码,也成为散列码,它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的检索位置。HashCode()在先列表中才有用,在其他的情况下是没用的,在散列表中HashCode()的作用是获取对象的散列码,从而确认对象在散列表中的位置。

  • HashCode()与equals()的相关规定
    1. 如果两个对象相等,则哈希码一定也是相同的
    2. 两个对象相等,对两个对象调用equals方法都返回true
    3. 两个对象具有相同的哈希码,他们也不一定相等的
    4. 如果equals方法又被覆盖过,那么hashcode()方法也必须被覆盖
    5. Hashcod()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等,即这两个对象指向相同的数据

5.简述线程,程序,进程的基本概念,以及他们之间的关系。

线程与进程相似,但是线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多少个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程或是各个线程切换工作时,负担要比进程小得多,也正因如此,线程也被成为轻量级进程

程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中。也就是说程序是静态的代码。

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源,如CPU时间,内存空间,文件,输入输出设备的使用权等等,换句话说,当程序在执行时,将会被操作系统载入内存中。线程是进程划分成更小的运行单位。线程和进程最大的不同在于:基本上各个进程是独立的,而各个线程咋不一定,因为统一进程中的线程极有可能相互影响。从另外一个角度来说,进程属于操作系统范畴,主要同一段时间内,可以同时执行一个以上的程序,而线程则是在同一个程序内几乎同时执行一个以上的程序段。

6.线程有哪些基本状态。

  • NEW

    初始状态,线程被构建,但是还没有调用start()方法

  • RUNNABLE

    运行状态,java线程将操作系统中的就绪和运行两种状态笼统的称作‘运行中’

  • BLOCKED

    阻塞状态,表示线程阻塞与锁

  • WAITING

    等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或者中断)

  • TIME_WAITING

    超时等待状态,该状态不同于WAITING,它是可以在指定的时间自行返回的

  • TERMINATED

    终止状态,表示线程已经执行完毕

线程创建之后它将处于NEW状态,调用start()方法后开始运行,线程这时候处于READY(可运行)状态。可运行状态获得了CPU时间片就处于RUNNING状态。

当线程执行wait()方法之后,线程进入WAITING(等待)状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而TIME_WAITING(超时等待)状态相当于在等待状态的基础上增加超时限制,比如通过sleep(long mills)方法或者wait(long mills)方法可以将Java线程至于TIMED WAITTING状态,当超时时间到达后JAVA线程将会返回到RUNNABLE状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到BLOCKED(阻塞)状态。线程在执行Runnable的run()方法之后将会进入到TERMINATED(终止)状态

7.Java中的异常处理。

在JAVA中,所有异常都有一个共同的祖先类,java.lang包中的Throwable类。Throwable:有两个重要的子类:Exception(异常)和Error(错误),二者都是JAVA异常处理的重要子类,各自都包含大量子类。

  • Error(错误)

    是程序无法处理的错误,表示运行应用程序中较为严重的问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时的JVM(JAVA虚拟机)出现的问题。例如JAVA虚拟机运行错误,当JVM不再有继续执行的操作所需的内存资源的时候,将出现OUTOFMEMORYERROR。这些异常发生时,JAVA虚拟机(JVM)一般会选择线程终止。

    还有类似类定义错误、虚拟机运行错误,这些错误表示故常发生于虚拟机自身,或者发生在虚拟机视图执行应用时,这些错误是不可查的,因为他们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不要试图去处理他所引起的异常状况。

  • Exception(异常)

    是成语本身可以处理的异常。Exception类又一个重要的子类RuntimeException。

    RuntimeException异常由JAVA虚拟机抛出。NullPointerException(要访问的变量没有任何对象时,抛出该异常)、ArithmeticException算术异常(分母为0)和ArrayIndexOutOfBoundsException(数组下标越界)

    他们两者的最大区别是,异常是可以被程序本身解决的,但是错误不可以,也不要尝试去用程序解决‘错误’

8.Spring、spring boot、SpringMVC的联系和区别

  • spring和springMvc:
  1. spring是一个一站式的轻量级的java开发框架,核心是控制反转(IOC)和面向切面(AOP),针对于开发的WEB层(springMvc)、业务层(Ioc)、持久层(jdbcTemplate)等都提供了多种配置解决方案;
  2. springMvc是spring基础之上的一个MVC框架,主要处理web开发的路径映射和视图渲染,属于spring框架中WEB层开发的一部分;
  • springMvc和springBoot:
  1. springMvc属于一个企业WEB开发的MVC框架,涵盖面包括前端视图开发、文件配置、后台接口逻辑开发等,XML、config等配置相对比较繁琐复杂;
  2. springBoot框架相对于springMvc框架来说,更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml,相对springmvc,大大简化了配置流程;
  • springBoot和springCloud:
  1. spring boot使用了默认大于配置的理念,集成了快速开发的spring多个插件,同时自动过滤不需要配置的多余的插件,简化了项目的开发配置流程,一定程度上取消xml配置,是一套快速配置开发的脚手架,能快速开发单个微服务;
  2. spring cloud大部分的功能插件都是基于springBoot去实现的,springCloud关注于全局的微服务整合和管理,将多个springBoot单体微服务进行整合以及管理; springCloud依赖于springBoot开发,而springBoot可以独立开发;
  3. Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring的ioc、aop等. ioc 提供了依赖注入的容器, aop解决了面向横切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能;
  4. springMvc是基于Servlet 的一个MVC框架主要解决WEB开发的问题,因为Spring的配置非常复杂,各种XML、JavaConfig、servlet处理起来比较繁琐;
  5. 为了简化开发者的使用,从而创造性地推出了springBoot框架,默认优于配置,简化了springMvc的配置流程;

    但区别于springMvc的是,springBoot专注于微服务方面的接口开发,和前端解耦,虽然springBoot也可以做成springMvc前后台一起开发,但是这就有点不符合springBoot框架的初衷了;

  6. 对于springCloud框架来说,它和springBoot一样,注重的是微服务的开发,但是springCloud更关注的是全局微服务的整合和管理,相当于管理多个springBoot框架的单体微服务;

9.RPC服务和restful服务的区别

  • 一、RPC

    即远程过程调用(Remote Procedure Call Protocol,简称RPC),像调用本地服务(方法)一样调用服务器的服务(方法)。通常的实现有 XML-RPC , JSON-RPC , 通信方式基本相同, 所不同的只是传输数据的格式.

RPC是分布式架构的核心,按响应方式分如下两种:

  • 同步调用:客户端调用服务方方法,等待直到服务方返回结果或者超时,再继续自己的操作
  • 异步调用:客户端把消息发送给中间件,不再等待服务端返回,直接继续自己的操作。

同步调用的实现方式有WebService和RMI。Web Service提供的服务是基于web容器的,底层使用http协议,因而适合不同语言异构系统间的调用。RMI实际上是Java语言的RPC实现,允许方法返回 Java 对象以及基本数据类型,适合用于JAVA语言构建的不同系统间的调用。

异步调用的JAVA实现版就是JMS(Java Message Service),目前开源的的JMS中间件有Apache社区的ActiveMQ、Kafka消息中间件,另外有阿里的RocketMQ。

RPC架构里包含如下4个组件:

1、 客户端(Client):服务调用方

2、 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数打包成网络消息,再通过网络发送给服务方

3、 服务端存根(Server Stub):接受客户端发送过来的消息并解包,再调用本地服务

4、服务端(Server):真正的服务提供者。

  • 二、REST

      REST即表述性状态传递(Representational State Transfer,简称REST),是一种软件架构风格。REST通过HTTP协议定义的通用动词方法(GET、PUT、DELETE、POST) ,以URI对网络资源进行唯一标识,响应端根据请求端的不同需求,通过无状态通信,对其请求的资源进行表述。

      Rest架构的主要原则:

  1. 网络上的所有事物都被抽象为资源
  2. 每个资源都有一个唯一的资源标识符
  3. 同一个资源具有多种表现形式(xml,json等)
  4. 对资源的各种操作不会改变资源标识符
  5. 所有的操作都是无状态的

    其中表述性状态,是指(在某个瞬间状态的)资源数据的快照,包括资源数据的内容、表述格式(XML、JSON)等信息。

    其中无状态通信,是指服务端(响应端)不保存任何与特定HTTP请求相关的资源,应用状态必须由请求方在请求过程中提供。要求在网络通信过程中,任意一个Web请求必须与其他请求隔离,当请求端提出请求时,请求本身包含了响应端为响应这一请求所需的全部信息。

    REST使用HTTP+URI+XML /JSON 的技术来实现其API要求的架构风格:HTTP协议和URI用于统一接口和定位资源,文本、二进制流、XML、JSON等格式用来作为资源的表述。

10.什么是SOA架构

面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构件在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。

面向服务架构,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署、组合和使用。服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理交互的人为依赖性。

SOA是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA可以看作是B/S模型、XML(标准通用标记语言的子集)/Web Service技术之后的自然延伸。

SOA将能够帮助软件工程师们站在一个新的高度理解企业级架构中的各种组件的开发、部署形式,它将帮助企业系统架构者以更迅速、更可靠、更具重用性架构整个业务系统。较之以往,以SOA架构的系统能够更加从容地面对业务的急剧变化。

SOA系统是一种企业通用性架构。

附注:自己总结,大部分手敲,有错误请谅解。