招银网络科技面经一
整个过程比较紧张,基本上都没有回答,这是事后整理的部分面试官问题。可能我太菜了,面试官问的简单。
1、python的数据结构
四种内置数据结构:列表list、元组tuple、字典dict、集合set
list的显著特征:
- 列表中的每个元素都可变的,意味着可以对每个元素进行修改和删除;
- 列表是有序的,每个元素的位置是确定的,可以用索引去访问每个元素
- 列表中的元素可以是Python中的任何对象;
- 可以为任意对象就意味着元素可以是字符串、整数、元组、也可以是list等Python中的对象。
元组Tuple,用法与List类似,但Tuple一经初始化,就不能修改,没有List中的append(), insert(), pop()等修改的方法,只能对元素进行查询
dict的显著特征:
- 字典中的数据必须以键值对的形式出现,即k,v:
key:必须是可哈希的值,比如intmstring,float,tuple,但是list,set,dict不行
value:任何值 - 键不可重复,值可重复
键若重复字典中只会记该键对应的最后一个值 - 字典中键(key)是不可变的,何为不可变对象,不能进行修改;而值(value)是可以修改的,可以是任何对象。
在dict中是根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。
集合的显著特征: - 集合更接近数学上集合的概念。集合中每个元素都是无序的、不重复的任意对象。
- 可以通过集合去判断数据的从属关系,也可以通过集合把数据结构中重复的元素减掉。集合可做集合运算,可添加和删除元素。
- 集合内数据无序,即无法使用索引和分片
- 集合内部数据元素具有唯一性,可以用来排除重复数据
- 集合内的数据:str,int,float,tuple,冰冻集合等,即内部只能放置可哈希数据
2、python的参数传递是引用和值传递
在python中将类型分为可变类型(包括列表、字典)和不可变类型(int\float\string\tuple)。
如何理解可变与不可变:在修改该类型变量时是否产生新对象,如果是在原对象上进行修改,为可变对象,如果是产生新的对象,则是不可变对象。在参数传递时,实参将标签复制给了形参,此时实参和形参都指向同一个对象。
在函数内修改形参:
- 对于不可变类型变量:因为不可变类型的特点,修改变量时需要创建一个新的对象,形参的标签指向新对象,实参没有变化,指向原对象;
- 对于可变类型变量:因为可变类型变量的特点,直接在原对象上修改,因而形参和实参指向同一个对象,所以形参改变了,实参也改变了
3、static关键字用法,可以修饰代码块
static关键字:方便在没有创建对象的情况下进行调用,即被static关键字修饰的不需要创建对象去调用,直接根据类名就可以访问。四个基本使用如下:
- 修饰类:static只能修饰一个静态内部类,即匿名内部类。作用在于可以直接将其作为一个普通类使用,不需要创建一个外部类的实例,而普通内部类的引用需要创建一个外部类的实例(参考:static修饰内部类)
- 修饰变量:被static修饰的成员变量叫做静态变量,也叫类变量,是属于类而不是对象,通过类名.变量名直接引用,不需要new一个对象;
- 修饰方法:被static修饰的方法叫做静态方法,也叫类方法,通过类名.方法名直接引用,不需要new一个对象;
- 静态代码块:指的是static{}包裹的代码块,在虚拟机加载类的时候执行,并且只执行一次,
执行顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类普通变量、父类普通代码块、、父类构造函数、子类普通变量、子类普通代码块、子类构造函数
问题一:JDK将不同的静态资源放在不同类中,而不是将其放在同一个类中,为什么?
1、不同的类有自己的静态资源,可以实现静态资源分配
2、避免重名。不同的类之间可以存在重名的静态变量名、静态方法名
3、避免静态资源类无限增加
问题二:静态方法能不能引用非静态资源?静态方法能不能引用静态资源?非静态方法能不能引用静态资源?
从JVM的类加载机制角度看,静态资源是类初始化的时候加载,非静态资源是类new的时候加载。类初始化早于类new操作。因此静态方法不能引用非静态资源(此时非静态资源还没有new操作),静态方法可以引用静态资源(都是类初始化的时候加载的),非静态方法可以引用静态资源(非静态方法也就是实例方法使用时,静态资源已经加载了,)
4、String类可以被继承吗?
不能,
String类的方法头是:public final class String extends Object
其中涉及修饰关键字final:
- 修饰类:这个类不能被继承,类中所有的方法被隐式的变为final方法
- 修饰方法:含有final方法的类可以被继承,但是final修饰的方法不能被重写
- 修饰变量:只能被赋值一次,当作常量使用也不可再更改,也必须被初始化,,可以在声明的时候,也可以在构造函数中
5、Java重载和重写的区别
重载(Overloading):位于同一个类之中,方法名相同,参数列表不同,参数的类型不同,返回值可以相同或不同;特征:
- 方法名必须相同‘
- 参数列表一定不同;
- 访问修饰符和返回值类型可以相同也可以不同;
重写(Overriding):子类继承父类时需要重写父类的方法,方法名相同(返回值类型相同),参数相同,具体的实现不同,特征: - 方法名必须相同,参数列表必须相同,返回值类型必须相同;
- 访问权限不能比父类中被重写的方法的访问权限低;
- 子类与父类在同一个包中,那么子类可以重写父类所有方法,除了final和private方法
- 构造方法不能被重写;
6、Java虚拟机的堆、栈区别
1、JVM栈(虚拟机栈)
栈帧:一个栈帧随着一个方法的调用开始而创建,调用结束而销毁。栈帧存放着方法的局部变量、操作数栈等数据。
每当启动一个线程时,Java虚拟机都会为其分配一个Java栈。Java以栈帧为单位保存线程运行状态,包含两种操作:以栈帧为单位进行入栈或出栈。
- 栈分为三部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
- 每个线程都有一个栈区,只保存了基础数据类型的对象和自定义对象的引用(对象存放在堆中)。
- 每个栈中的数据(原始类型和对象引用)都是私有的,不能为其他栈访问
- 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
2、堆内存(Heap Memory)
jvm只有一个堆区,被所有线程共享,只存放对象本身,不存放基本类型和对象的引用。
优点:可以动态分配内存大小,生存期也不必事先告诉编译器(因为是在运行时存放对象本身,gc也会自动收走不再使用的数据)
缺点:由于要在运行时动态分配内存,存取速度慢
3、方法区
方法区是被线程共享的区域,存储了每个类的信息(类名、方法、字段信息)、静态变量、常量以及编译器编译后的代码等。
在class文件中除了类的字段、方法、接口等描述信息,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。
在方法区中还有一个部分是运行时常量池,是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的常量池就被创建。
4、本地方法栈
和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。
Java官方对于本地方法的定义为methods written in a language other than the Java programming language,就是使用非Java语言实现的方法,但是通常我们指的一般为C或者C++,因此这个栈也有着C栈这一称号。一个不支持本地方法执行的JVM没有必要实现这个数据区域。本地方法栈基本和JVM栈一样,其大小也是可以设置为固定值或者动态增加,因此也会对应抛出StackOverflowError和OutOfMemoryError错误。
5、程序计数器
程序计数器是线程私有,所以当一个新的线程创建时,程序计数器也会创建。由于Java是支持多线程,Java中程序计数器用来记录当前线程中正在执行的指令。如果当前正在执行的方法是本地方法,那么此刻程序计数器的值为undefined。注意这个区域是唯一一个不抛出OutOfMemoryError的运行时数据区。
7、tcp和udp的区别,tcp如何确保可靠性?
TCP | UDP | |
---|---|---|
是否连接 | 面向连接 | 无连接 |
是否可靠 | 可靠传输,使用了流量控制和拥塞控制 | 不可靠传输 |
连接对象个数 | 只能一对一通信 | 支持一对一,一对多,多对一,多对多交互通信 |
传输方法 | 面向字节流 | 面向报文 |
首部开销 | 首部开销最小20字节,最大60字节 | 首部开销小,仅仅8个字节 |
适用场景 | 适用于要求可靠传输的应用,例如文件传输 | 适用于实时应用(IP电话、视频会议、直播等) |
TCP(传输控制协议)是面向连接的、可靠的、基于字节流的传输层通信协议,特点:
- 面向连接:是指发送数据之前必须在两端建立连接,(“三次握手”),这样可以可靠性传输;
- 仅支持单播传输:每条TCP传输连接只能两个端点,进行点对点的输出传输,不支持多播和广播传输
- 面向字节流:在不保留报文边界的情况下以字节流方式进行传输。
- 可靠传输:判断丢包、误码依赖的是TCP的序号(seq)和确认号(ack),TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
- 拥塞控制:当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞
- 提供全双工通信:TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)
UDP(用户数据报协议)是无连接的,不可靠的、面向报文的传输层通信协议,特点:
- 面向无连接:在发送端,应用层将数据传递给传输层的UDP协议,UFP只给数据增加一个UDP头标识,然后传给网络层,在接收端直接去除豹纹头,不会进行任何拼接操作
- 有单播、多播、广播功能:UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
- 面向报文:发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文
- 不可靠性:一是体现在无连接上,收到什么数据就传递什么数据,不会备份,也不会确认对方是否收到;二是网络环境不确定时,没有拥塞控制,在网络条件不好时容易丢包
- 头部开销小(仅仅8个字节),传输数据报文时很高效:UDP 头部包含了以下几个数据:两个十六位的端口号,分别为源端口(可选字段)和目标端口;整个数据报文的长度;整个数据报文的检验和(IPv4 可选 字段),该字段用于发现头部信息和数据中的错误
8、针对有范围的n个数字选择哪种排序?
9、插入排序的时间复杂度和数据规模是同步增长的吗?
10、group by \where\from\limit等的顺序