- 自我介绍
- 成绩怎样?
- 实验室相关;Java开发相关
- 博客 github
- 说说自己对Java这门语言的理解;
当时的回答主要是针对可移植性和生态健全这两个方面来说了一些自己的看法。
Java语言是一种面向对象的高级语言,它最显著的有两个特性,一是通过平台中立的class文件格式和屏蔽底层硬件差异的jvm实现‘一次编写,到处运行’;二是通过‘垃圾收集器’管理内存的分配和回收。
-
Java是纯面向对象的语言。《Java编程思想》中提到Java语言是一种“Everything is object”的语言,它能够直接反映现实生活中的对象,例如车、动物等,因此通过它编写程序更容易。
-
平台无关性。Java语言可以“一次编译,到处执行”。无论是在Windows平台还是在Linux、MacOS等其他平台上对Java程序进行编译,编译后的程序在其他平台上都可以运行。由于Java是解释性语言,编译器会将Java代码变成“中间代码”,然后在Java虚拟机(Java Virtual Machine,JVM)上解释执行。由于中间代码与平台无关,因此Java语言可以很好的跨平台执行,具有很好的可移植性。
-
Java提供了很多内置的类库,通过这些类库,简化了开发人员的程序设计工作,同时缩短了项目的开发时间,例如,Java语言提供了对多线程的支持,提供了对网络通信的支持,最主要的是提供了垃圾回收器,这使得开发人员从内存的管理中解脱出来。
-
提供了对Web应用开发的支持。例如,Applet、Servlet和JSP可以用来开发Web应用程序;Socket、RMI可以用来开发分布式应用程序。
-
具有较好的安全性和健壮性。Java语言经常被用在网络环境中,为了增强程序的安全性,Java语言提供了一个防止恶意代码攻击的安全机制(数组边界检测和Bytecode校验等)。Java的强类型机制、垃圾回收器、异常处理和安全检查机制使得用Java语言编写的程序具有很好的健壮性。
-
去除了C++语言中难以理解、容易混淆的特性,如头文件、指针、结构、单元、运算符重载、虚拟基础类、多重继承等,使得程序更加严谨简洁。而且由垃圾收集齐来管理的内存分配和回收。
-
Java 是解释执行+编译执行混合型。一般JVM 是直接解释执行.class文件,当出现高频代码时JVM 会通过JIT 即时编译器把经常运行的代码作为"热点代码"编译与本地平台相关的机器码,并进行各种层次的优化
- Java的class文件能够被修改吗?为什么
可以通过可视化工具和Javassist库来直接对Class文件进行修改。
- 可视化方式
首先从 JBE 下载 JBE(Java Bytecode Editor),JBE是一个用于浏览和修改Java Class文件的开源软件。 - Javassist 方法
Javassist天生就是为修改Java字节码而来的,它提供了源代码和字节码两种级别的API接口,为了实现的简便性
- final关键字,在JDK中在哪些场景用到了final ?
-
final 修饰类
当用final修饰一个类时,表明这个类不能被继承。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。 -
修饰方法
把方法锁定,以防任何继承类修改它的含义,类的private方法会隐式地被指定为final方法。 -
修饰变量
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改,而且必须在定义时或者构造器中进行初始化;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
String 类中使用final关键字修饰字符数组来保存字符串的。Java9之后是用final的byte数组来存储的。
- final 修饰的hashMap对象还能往容器里面put对象吗?
这个hashMap是指该引用是final啦,但是map里面的值不是final的,所以可以继续往里面put内容。但是如果把这个hashmap的引用指向另个一个hashmap就会抛异常。 - Object里面的方法?
有hashcode(),equals(), clone(), toString()方法 - 对notify()和notifyAll()方法了解
notify()/notifyAll():唤醒在此对象监视器上等待的单个线程/所有线程。
假设现在有两个对象分别是A和B,有1,2,3三个线程在等待A,4,5,6三个线程咋等待B。
当A调用notifyAll哪几个线程被唤醒。答案是123.
11.hashmap的put和get流程?
put方法的流程:
part1:特殊key值处理,key为null;
part2:计算table中目标bucket的下标;
part3:指定目标bucket,遍历Entry结点链表,若找到key相同的Entry结点,则做替换;
part4:若未找到目标Entry结点,则新增一个Entry结点。
**put()
**方法是有返回值的,场景区分如下:
- 场景1:若执行put操作前,key已经存在,那么在执行put操作时,会使用本次的新value值来覆盖前一次的旧value值,返回的就是旧value值;
- 场景2:若key不存在,则返回null值。
特殊key值,指的就是key为null。 先说结论:
a) HashMap中,是允许key、value都为null的,且key为null只存一份,多次存储会将旧value值覆盖;
b) key为null的存储位置,都统一放在下标为0的bucket,即:table[0]的位置;
扩容
a) 扩容后大小是扩容前的2倍;
b) 数据搬迁,从旧table迁到扩容后的新table。 为避免碰撞过多,先决策是否需要对每个Entry链表结点重新hash,然后根据hash值计算得到bucket下标,然后使用头插法做结点迁移。
- 有一个Apple类,其中有两个内容相同的对象为A和B,现在有一个hashmap对象map,map.put(A,1000)。能用map.get(B)获取到数据吗?
不能,因为在put的时候用的是A对象的hashcode,经过一系列的计算作为KEY值,现在用B来获取的时候,B的hashcode与A不同,所以是获取不到的。可以在Apple类中将hashcode和equals方法进行覆写就可以实现这样的操作。
public class Apple{
String name;
String location;
int format;
public Apple(String name,String loc,int formate){
this.name = name;
this.location = loc;
this.format = formate;
}
public String getName(){
return name;
}
public String getLocation(){
return location;
}
Object o;
@Override
public int hashCode(){
int hash = (name + location + format).hashCode();
System.out.println(hash);
return hash;
}
@Override
public boolean equals(Object obj) {
Apple o = (Apple) obj;
boolean formatBoolean = this.location.equals(o.getLocation());
boolean nameBoolean = this.name.equals(o.getName());
return formatBoolean && nameBoolean ;
}
}
import java.util.*;
public class Test {
public static void main(String[] args) {
Apple apple = new Apple("app", "xian", 1000);
Map<Apple, Integer> map = new HashMap<>();
map.put(apple, 100);
Apple apple2 = new Apple("app", "xian", 1000);
System.out.println(map.get(apple2));
}
- java8的一些新特性?
Lambda表达式,函数式接口
接口的默认方法和静态方法
流式编程 - 一个项目部署到Linux上的流程都是什么?
- 申请虚拟机安装一个server版的centos系统。
- 配置jdk环境。
- 安装Tomcat,并将Tomcat注册为系统服务,或者编写脚本监控Tomcat服务是否正常。
- 将我们打包好的web服务放到Tomcat的root目录里面。
-
在springboot中自带的Tomcat运行时,如何将命令保持在后台运行?
nohup /usr/local/node/bin/node /www/im/chat.js >> /usr/local/node/output.log 2>&1 & -
端口占用
netstat -ap | grep 8080
lsof -i :8080 -
查看进程
ps -ef | grep tomcat -
docker的特性?
Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码在我机器上没问题啊” 这类问题;——一致的运行环境
可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。——更快速的启动时间
避免公用的服务器,资源会容易受到其他用户的影响。——隔离性
善于处理集中爆发的服务器使用压力;——弹性伸缩,快速扩展
可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。——迁移方便
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。——持续交付和部署
springboot配置
CAP ZK
springcloud
项目亮点
代码:
二叉树翻转:
public class Soluion {
TreeNode invertTree(TreeNode root){
if(root == null){
return null;
}
TreeNode left = root.left;
root.left = invertTree(root.rigth);
root.rigth = invertTree(left);
return root;
}
}
检查单链表是否有环,如果有环的话,找出环的入口?
public class CycleList {
public ListNode hasCycle(ListNode head){
if(head == null){
return null;
}
ListNode quick = head;
ListNode slow = head;
ListNode slow2 = head;
while(quick.next != null && quick.next.next != null){
quick = quick.next.next;
slow = slow.next;
if(quick == slow){
while(slow2 != slow){
slow2 = slow2.next;
slow = slow.next;
}
return slow2;
}
}
return null;
}
public ListNode hasCycle1(ListNode head){
if(head == null){
return null;
}
LinkedHashSet<ListNode> set = new LinkedHashSet();
while (head != null){
if(set.contains(head)){
return head;
}else {
set.add(head);
head = head.next ;
}
}
return null;
}
``