技术干货IT面试

基础知识(一)网络和java相关

2018-10-05  本文已影响27人  胖胖O蓝胖子

OSI七层模型与五层网络模型:

(1)OSI七层模型

OSI中的层 功能 TCP/IP协议族

应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet

表示层 数据格式化,代码转换,数据加密 没有协议

会话层 解除或建立与别的接点的联系 没有协议

传输层 提供端对端的接口 TCP,UDP

网络层 为数据包选择路由 IP,ICMP,RIP,OSPF,BGP,IGMP

数据链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU

物理层 以二进制数据形式在物理媒体上传输数据 ISO2110,IEEE802,IEEE802.2

(2)TCP/IP五层模型的协议

物理层:中继器、集线器、还有我们通常说的双绞线也工作在物理层

数据链路层:网桥(现已很少使用)、以太网交换机(二层交换机)、网卡(其实网卡是一半工作在物理层、一半工作在数据链路层)

网络层:路由器、三层交换机

传输层:四层交换机、也有工作在四层的路由器

HTTP 通信过程:

1.tcp建立链接(三次握手)

2.浏览器发送请求命令

3.浏览器发送请求头消息

4.服务器应答

5.服务器回应头信息

6.服务器发送数据

7.断开tcp链接(四次挥手)

三次握手和四次挥手:TCP三次握手详解及释放连接过程 - 老王子的博客 - 博客园

握手

1.客户端到服务器,syn=1 ACK=0 seq=x 

2.服务器到客户端,syn=1 ack=x+1 seq=x ACK=1

3.客户端到服务器,ACK=1 seq=x+1 ack=y+1

挥手

1.第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

2.第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。等待2MSL时间。

3.第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

4.第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

http请求包括:请求行,请求头,空行,数据

http相应包括:响应行,相应头和相应体

http请求头主要内容:

accept:浏览器处理内容类型

accept-charset:浏览器显示的字符集

accept-encoding:浏览器处理的编码

accept-language:浏览器当前设置的语言

connection:浏览器和服务器建立的链接类型

cookie:当前页面的cookie设置

host:当前页面所在区域

reference:url

user-agent:浏览器当前用户代理字符串

http响应头主要内容:

date:发送时间

server:服务器名字

connection:服务器和客户端链接类型

content-type:文档类型(text、application、voice、message、video等)

cache-control:http缓存

http与https比较以及http版本变化:

https为密文传递信息,安全通道,等于http+ssl,端口号为443

http为明文传递信息,端口号为80

http1.0 的keep-alive保持长链接,http1.1默认支持长链接,支持只发送header,host域,多建立链接,请发请求。

http常见的异常码:常见的http异常状态码 - qq_37819347的博客 - CSDN博客

400系列为请求错误

500系列为服务器错误

https连接过程,握手过程

建立服务器443端口连接

SSL握手:随机数,证书,密钥,加密算法

发送加密请求

发送加密响应

关闭SSL

关闭TCP

网络请求流程:

1.dns解析域名

2.tcp三次挥手建立链接

3.建立链接

4.浏览器发起http链接请求

5.服务器相应请求

6.浏览器解析加载

get、post、put比较:

GET:向特定的资源发出请求。 

POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改。 (创建和更新两个作用)

PUT:向指定资源位置上传其最新内容。 (主要用于更新某一内容)

get通过url传递参数,post放在requestbody中,get相比post更不安全,get只能在url编码,产生一个tcp数据包,把header和post一起发出去。post 产生两个数据包,先发送header-----服务器相应-----发送data----服务相应,get由于通过url传递参数,有长度限制。

udp与tcp:

udp:非面向链接、传输不可靠、应用场合数量较多、链接速度快,可能丢包、不保证顺序、数据报文模式、多用于语音、视频

tcp:面向链接、传输可靠、应用场合较少、速度慢、保证数据正确和顺序、采用数据流模式

常用协议:

应用层:ftp、http、telent、ntp、smtp

传输层:tcp、udp

网络层:IP 、ARP、 PAPR

java锁:

保证一个线程访问object,其他线程对object同步。同步代码块时,获得这个object的对象锁,代码块访问都会阻塞。

volatile:

volatile标志的变量,当线程修改了变量的值,其他线程可以立即知道该变量的改变。然而对于普通变量来说,当一个线程修改了变量,需要先将变量写回主内存,其他线程从主内存读取变量后才对该线程可见。似乎从以上的描述可以推导出只要使用volatile修饰的变量就可以保证该变量在多线程环境下操作是安全的,因为它对于所有线程的工作内存都是可见的也就是说一致的。

java中常见同步与异步集合类型:

同步:vector、HashTable、properties、stack、ConcurrentHashMap等

异步:ArrayList、HashMap等

hashcode作用:

创建类型对应散列表,两个相同的对象hashcode值相等,equal返回为true。

解决hash冲突:解决Hash冲突的几种方法 - qq_35124535的博客 - CSDN博客

hash构造最为常用且简单的为除留余数法:哈希表长为m,p为小于等于m的最大素数,则哈希函数为

h(k)=k  %  p ,其中%为模p取余运算。

若产生冲突可采用如下的两种常用方法:

开放定址法

这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。这种方法有一个通用的再散列函数形式:

线性探测再散列

这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

==和equal:

基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,boolean。他们之间的比较,应用双等号(==),比较的是他们的值。

复合数据类型(类):当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址(确切的说,是堆内存地址)。

注:对于第二种类型,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。因为每new一次,都会重新开辟堆内存空间。

在Object类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址,但在一些类库当中这个方法被复写了,如String、Integer、Date。在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。 

所以说,对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是内存中的存放位置的地址值,跟双等号(==)的结果相同;

String、StringBuffer与StringBuilder的区别:String,StringBuffer与StringBuilder的区别?? - Java天空 - CSDN博客

StringBuffer 字符串变量(线程安全)

StringBuilder 字符串变量(非线程安全)

String 

简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。

而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的.

思考:String 为什么要设计成不可变的?答案就在上面文字中。

StringBuffer

Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

java.lang.StringBuilde

java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

集合:

三个主要接口:

set:不包含重复内容

list:有序集合

map:键值对形式存储

经常对比的HashMap与HashTable

HashMap:允许key和value为null,为非同步的单线程(不安全线程),可以转化为LinkHashMap遍历,提供了对key的set遍历。

Hashmap实现原理:HashMap是一个散列集合,其底层是数组+链表结构,主体部分是个长度很长的数组,主体 : Entry数组(实际存key,value的对象),链表 : 通过next方法指向链表下一个结点

HashTable:key和value部允许为null,是同步安全的线程,存储内容顺序不可知,提供了对key的Enumeration遍历方式。

较为新的集合:sparseArray省内存,进行了压缩操作,key必须为整型,使用二分查找法进行查寻。

关于object类:

object提供了:clone,getclass,equals,tostring,notify/notifyall,wait,finalize等方法,其中wait释放了当前操作对象的控制,wait是object提供的方法,而sleep是thread提供的方法,要区分对待。

JVM体系:

1.类型加载:加载.class文件。

类加载机制:查找导入class文件,二进制数据合并到jre中,校验正确性,给静态量分配空间,将符号变为引用,对类静态部分进行初始化。

java对象的引用包括:Java的四种引用方式 - 空谷幽澜 - 博客园

强引用,软引用,弱引用,虚引用

强引用: 是指创建一个对象并把这个对象赋给一个引用变量。强引用有引用变量指向时永远不会被垃圾回收,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。

软引用:如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;

弱引用:也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

2.执行引擎:执行字节码文件。

3.运行时数据区域:方法区,堆区,java栈,寄存器,本地方法栈。

方法区和堆区为共享:

方法区存放:类信息,常量,静态量

堆区:主要存放对象

java栈,本地方法栈和程序计数器为私有:

java栈:基本类型,局部变量

本地方法栈:native方法

程序计数器:执行字节码行号指示器

java读取文件:

1.FileInputStream/ FileOutputStram 字节流

2.FileReader/  FileWrite 字符流

3.BufferedReader/BufferedWrite 带缓冲区

速度比较:3>2>1

IO操作是通过object.OutputStream的流机制实现的通常分为三类:

BIO:同步阻塞

NIO:同步非阻塞

AIO:异步阻塞

Error和Exception的简单比较:

Error:不可控制,系统级的错误引发,被系统捕捉。

Exception:可控和不可控都有,大多数由于人的原因导致引发,在应用程序级别被处理,常见的exception分类为RuntimeException和非RuntimeException。

接口和抽象类的简单比较:

接口:interface 名 定义,主要包括:抽象方法,全局常量,普通方法,static部分,权限为public,接口不允许接抽象类,可extend一个父接口。

抽象类:abstract class 名 定义,主要包括:构造方法,普通方法,静态方法,全局常量,成员变量等,权限为任意,但类不能用final修饰,因为final修饰的类不能被继承,故抽象类不能采用。

使用方面:两者必须定义子类,子类必须重写抽象方法,通过子类向上转型获取抽象类或者接口的对象。同等情况下优先考虑使用接口,接口使用的意图:进行标注的设定,表示一种操作能力,暴露远程方法视图。

内部类和外部类的调用:

a)内部类可以直接调用外部类的包括private的成员变量,使用外部类引用的this关键字即可

b)外部类调用内部类需要建立内部类对象;

GC回收策略较为复杂参考:Java垃圾回收(GC)机制详解 - 平凡希 - 博客

线程池:

ThreadPoolExecutor参数:

int CorePoolSize 核心线程数最大值

int MaximumPoolPize 线程总数最大值(线程总数=核心线程数+非核心线程数)

long keepAlive Time 非核心线程闲置超时时长

Blocking Queue<Runnable> workQueue 任务队列

Thread Factory 线程工厂(创建线程的方式)

Rejected ExceptionHandler  抛出异常的handler

常见的四种线程池:

1.CacheThreadPool 可缓存的线程池:线程无限制,又空闲则复用,无空闲则常见,主要减少了频繁的创建和销毁线程,减少了系统的开销。

ExecutorService cachedThreadPool=Executors.newCachedThreadPool()

2.FixedThreadPool 定长线程池:控制最大的并发,超出等待。

ExecutorService fixedThreadPool=Executors.newFixedThreadPool(int nThreads)

3,ScheduledThreadPool 支持定时及周期执行任务

ExecutorService scheduledThreadPool=Executors.newScheduledThreadPool()

//延迟三秒执行

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  

scheduledThreadPool.schedule(new Runnable() {  

public void run() {  

System.out.println("delay 3 seconds");  

   }  

},3, TimeUnit.SECONDS); 

//延迟1秒后3秒为周期执行

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {  

publicvoid run() {  

System.out.println("delay 1 seconds, and excute every 3 seconds");  

   }  

},1,3, TimeUnit.SECONDS);  

4.SingleThreadExecutor 单线程线程池:有且只有一个工作线程执行,按照顺序先进先出(FIFO),

ExecutorService singleThreadPool=Executors.newSingleThreadPool()

未完待续..............

上一篇下一篇

猜你喜欢

热点阅读