2019年_BATJ大厂面试题总结-字节跳动篇

1.hashmap,hashmap扩容是需要重新哈希吗?如果二次哈希后还是哈希冲突呢?

答案:https://blog.csdn.net/u012712901/article/details/78313130?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

2.integer和int的自动装箱和拆箱以及为什么要用integer类

1.答案:https://www.cnblogs.com/aishangtaxuefeihong/p/4886997.html
2.答案:
如果返回字段值为null,int类型会报错,Integer不会报错。因为int类型声明的是变量,而null是对象所以会报错。Integer是包装类,包装类符合对象的特征并提供了一些必要的属性和方法。

int类型的默认值为0,Integer类型的默认值为null。
详解:https://blog.csdn.net/myme95/article/details/81703216

3.Java的线程都有哪几种状态

java线程状态在Thread中定义,源码中能看到有个枚举State,总共定义了六种状态:

NEW: 新建状态,线程对象已经创建,但尚未启动

RUNNABLE:就绪状态,可运行状态,调用了线程的start方法,已经在java虚拟机中执行,等待获取操作系统资源如CPU,操作系统调度运行。

BLOCKED:堵塞状态。线程等待锁的状态,等待获取锁进入同步块/方法或调用wait后重新进入需要竞争锁

WAITING:等待状态。等待另一个线程以执行特定的操作。调用以下方法进入等待状态。 Object.wait(), Thread.join(),LockSupport.park

TIMED_WAITING: 线程等待一段时间。调用带参数的Thread.sleep, objct.wait,Thread.join,LockSupport.parkNanos,LockSupport.parkUntil

TERMINATED:进程结束状态。

状态之间的转换状态图,总结了下,如下:
在这里插入图片描述

其中,Thread.sleep(long)使线程暂停一段时间,进入TIMED_WAITING时间,并不会释放锁,在设定时间到或被interrupt后抛出InterruptedException后进入RUNNABLE状态; Thread.join是等待调用join方法的线程执行一段时间(join(long))或结束后再往后执行,被interrupt后也会抛出异常,join内部也是wait方式实现的。

wait方法是object的方法,线程释放锁,进入WAITING或TIMED_WAITING状态。等待时间到了或被notify/notifyall唤醒后,回去竞争锁,如果获得锁,进入RUNNABLE,否则进步BLOCKED状态等待获取锁。

下面是一个小例子,主线程中调用多线程,等待超时后如果子线程还未结束,则中断子线程(interrupt)。
在这里插入图片描述
在这里插入图片描述

4.Java堆中有哪些GC算法

最全的:https://blog.csdn.net/xinlingchengbao/article/details/88369528

5.Java有哪些引用类型,分别是什么特点

答案:https://blog.csdn.net/qq_19704045/article/details/80646437

6.JMM模型,内存可见性介绍下

答案:https://blog.csdn.net/bryce123phy/article/details/52260168

7.JVM内存模型分为哪几个区域

CSDN:https://blog.csdn.net/qq_24499615/article/details/80012470
博客园:https://www.cnblogs.com/mengchunchen/p/7819370.html

8.static final修饰的一个int 进行修改后是否需要进行重新编译

博客园:https://www.cnblogs.com/AceIsSunshineRain/p/5058279.html
CSDN:https://blog.csdn.net/stormwy/article/details/8435136

9.synchronized和volatile区别

1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;
synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。

2.volatile仅能使用在变量级别;
synchronized则可以使用在变量、方法、和类级别的

3.volatile仅能实现变量的修改可见性,不能保证原子性;
而synchronized则可以保证变量的修改可见性和原子性

4.volatile不会造成线程的阻塞;
synchronized可能会造成线程的阻塞。

5.volatile标记的变量不会被编译器优化;
synchronized标记的变量可以被编译器优化
详解:https://blog.csdn.net/suchahaerkang/article/details/80456085

10.wait()和sleep()有什么区别

1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!)。

wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);

2、sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;

3、sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;
详解:https://blog.csdn.net/weixin_39843989/article/details/90294825

11.并发中的方法

处理高并发的六种方法

1:系统拆分,将一个系统拆分为多个子系统,用dubbo来搞。然后每个系统连一个数据库,这样本来就一个库,现在多个数据库,这样就可以抗高并发。

2:缓存,必须得用缓存。大部分的高并发场景,都是读多写少,那你完全可以在数据库和缓存里都写一份,然后读的时候大量走缓存不就得了。毕竟人家redis轻轻松松单机几万的并发啊。没问题的。所以你可以考的虑考虑你的项目里,那些承载主要请求读场景,怎么用缓存来抗高并发。

3:MQ(消息队列),必须得用MQ。可能你还是会出现高并发写的场景,比如说一个业务操作里要频繁搞数据库几十次,增删改增删改,疯了。那高并发绝对搞挂你的系统,人家是缓存你要是用redis来承载写那肯定不行,数据随时就被LRU(淘汰掉最不经常使用的)了,数据格式还无比简单,没有事务支持。所以该用mysql还得用mysql啊。那你咋办?用MQ吧,大量的写请求灌入MQ里,排队慢慢玩儿,后边系统消费后慢慢写,控制在mysql承载范围之内。所以你得考虑考虑你的项目里,那些承载复杂写业务逻辑的场景里,如何用MQ来异步写,提升并发性。MQ单机抗几万并发也是ok的。

4:分库分表,可能到了最后数据库层面还是免不了抗高并发的要求,好吧,那么就将一个数据库拆分为多个库,多个库来抗更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高sql跑的性能。

5:读写分离,这个就是说大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库。

6:solrCloud:
SolrCloud(solr 云)是Solr提供的分布式搜索方案,可以解决海量数据的 分布式全文检索,因为搭建了集群,因此具备高可用的特性,同时对数据进行主从备份,避免了单点故障问题。可以做到数据的快速恢复。并且可以动态的添加新的节点,再对数据进行平衡,可以做到负载均衡:

12.抽象类和接口的区别,什么时候用抽象类什么时候用接口

CSDN:https://blog.csdn.net/wb_snail/article/details/78862533
简书:https://www.jianshu.com/p/914e8e1a320a
博客园:https://www.cnblogs.com/qf-dd/p/10109916.html

13.问题:反转链表按k,最长重复子串

答案;面向对象和面向过程、jvm垃圾回收

14.介绍2个设计模式

答案:https://www.cnblogs.com/aspirant/p/8979340.html

15.Java堆中有哪些GC算法

答案:https://blog.csdn.net/samniwu/article/details/90613989

16.内存泄漏是什么,怎么检测

CSDN:https://blog.csdn.net/xiaodu655/article/details/81153020
简书:https://www.jianshu.com/p/fd741fb87dc5

17.什么是线程池

CSDN:https://blog.csdn.net/weixin_40271838/article/details/79998327
博客园:https://www.cnblogs.com/victorwux/p/9004564.html

18.算法题

1.给一个链表1->2->3->4->5->6->7 和 一个数字n;每n个反转一次链表。
如 n = 2时,2->1->4->3->6->5->7;n = 3时,3->2->1>6->5->4->7

public class NodeReverse {
 
	public static void main(String[] args) {
		int a[] = { 1, 2, 3, 4, 5, 6, 7 };
		Node root = new Node(a[0]);
		Node head = root;
		for (int i = 1; i < a.length; i++) {
			Node node = new Node(a[i]);
			head.next = node;
			head = node;
		}
		root = reverseAdjacentNode(root);
		System.out.print("相邻元素翻转后:");
		while (root != null) {
			System.out.print(root.data);
			root = root.next;
			if(root != null) {
				System.out.print("->");
			}
		}
	}
 
	private static Node reverseAdjacentNode(Node root) {
		Node head = root;
		Node p, q = null;
		if (root.next != null) {
			root = root.next;  //根结点为第二个结点
		} else {
			return root;
		}
		int flag = 0;  //判断P是否为第一个结点
		p = head;
		q = head.next;
		while(p!= null) {
			if(flag == 0) {  //p为第一个结点
				p.next = q.next;
				q.next = p;
				flag = 1;
			} else {
				if(p.next == null) {
					break;
				}
				head.next = q;   
				p.next = q.next;
				q.next = p;
			}
			head = p; //保留下一个p前面的结点
			p = p.next;
			q = p.next;
		}
		return root;
	}
}
 
class Node {
	public int data;
	public Node next;
 
	public Node(int data) {
		this.data = data;
		this.next = null;
	}
 
}
</span>

2.罗马数字转整数 leetcode13
详解:https://www.cnblogs.com/ariel-dreamland/p/9128055.html

19.算法题: 反转链表,删除排好序数组中重复元素,第一题秒了,第二题用两根指针卡了可能1分钟在左指针的移动上。

参考:https://blog.csdn.net/SoulOH/article/details/81630807

20.推荐系统,考虑过分布式系统嘛,QPS怎么测试出来

参考:https://blog.csdn.net/silyvin/article/details/79143761

21.消费者生产者,写写伪代码

答案:https://blog.csdn.net/yongf2014/article/details/46493129

22.写一个list删除目标元素的函数,然后写个测试用例测试一下能不能通,为什么不能正向遍历

参考:https://blog.csdn.net/qinaye/article/details/81875199

23.虚引用有哪些应用场景

答案:Java的强引用,软引用,弱引用,虚引用及其使用场景

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值