最后的内容
在开头跟大家分享的时候我就说,面试我是没有做好准备的,全靠平时的积累,确实有点临时抱佛脚了,以至于我自己还是挺懊恼的。(准备好了或许可以拿个40k,没做准备只有30k+,你们懂那种感觉吗)
如何准备面试?
1、前期铺垫(技术沉积)
程序员面试其实是对于技术的一次摸底考试,你的技术牛逼,那你就是大爷。大厂对于技术的要求主要体现在:基础,原理,深入研究源码,广度,实战五个方面,也只有将原理理论结合实战才能把技术点吃透。
下面是我会看的一些资料笔记,希望能帮助大家由浅入深,由点到面的学习Java,应对大厂面试官的灵魂追问
这部分内容过多,小编只贴出部分内容展示给大家了,见谅见谅!
- Java程序员必看《Java开发核心笔记(华山版)》
- Redis学习笔记
- Java并发编程学习笔记
四部分,详细拆分并发编程——并发编程+模式篇+应用篇+原理篇
- Java程序员必看书籍《深入理解 ava虚拟机第3版》(pdf版)
- 大厂面试必问——数据结构与算法汇集笔记
其他像Spring,SpringBoot,SpringCloud,SpringCloudAlibaba,Dubbo,Zookeeper,Kafka,RocketMQ,RabbitMQ,Netty,MySQL,Docker,K8s等等我都整理好,这里就不一一展示了。
2、狂刷面试题
技术主要是体现在平时的积累实用,面试前准备两个月的时间再好好复习一遍,紧接着就可以刷面试题了,下面这些面试题都是小编精心整理的,贴给大家看看。
①大厂高频45道笔试题(智商题)
②BAT大厂面试总结(部分内容截图)
③面试总结
3、结合实际,修改简历
程序员的简历一定要多下一些功夫,尤其是对一些字眼要再三斟酌,如“精通、熟悉、了解”这三者的区别一定要区分清楚,否则就是在给自己挖坑了。当然不会包装,我可以将我的简历给你参考参考,如果还不够,那下面这些简历模板任你挑选:
以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
}
public static void main(String[] args) {
TuziArrayList list = new TuziArrayList();
for (int i = 0; i < 12; i++) {
list.add(i);
}
System.out.println(list);
}
===========================================================================
remove方法用来删除某一个元素。
步骤 1 两种删除方法
首先,我们看下ArrayList的remove方法是怎么做的。
第一种,是通过下标删除。
public E remove(int index)
第二种,是根据对象删除。
public boolean remove(Object o)
步骤 2 根据下标删除
这个下标其实就是内部数组的下标,众所周知,数组删除元素一向是个令人头疼的问题,下面演示一种推荐的做法,没错,还是用arrayCopy方法。
假如数组是这样的:
我想要删除元素2,也就是index = 1的位置。
2拿掉,后面的3和4左移一个单位不就好了吗?
再复习一下之前arrayCopy的用法:
System.arraycopy(src, srcPos, dest, destPos, length);
参数的含义(看了api,我反复琢磨以后,感觉这样翻译比较好)
src : 需要拷贝的数组。
srcPos : 从哪里开始 拷贝?
dest : 目标数组
destPos : 从哪里开始 粘贴?
length : 拷贝的元素个数
憋口气,一下子就写出下面的代码:
System.arraycopy(array, index+1, array, index, size - index -1);
size是4,index是1,所以size-index-1就是2, 什么 是快乐星球?
哦不好意思,跑错片场了。
2是什么,2不就是后面需要移动的元素个数嘛!所以,最后一个参数就是拷贝的元素个数。
但是,这样一来就有个问题:
如图,因为数组的长度还是4,remove掉一个元素后,最后一个位置就空了。我们需要手动把它置为空,这里如果不置空,它将会保存着一个引用,那么垃圾收集器将无法回收它,可能会造成内存泄漏。
最终源码:
public Object remove(int index){
//边界检测方法
rangeCheck(index);
Object oldValue = array[index];
System.arraycopy(array, index+1, array, index, size - index -1);
array[–size] = null;
return oldValue;
}
private void rangeCheck(int index) {
if(index < 0 || index >= size){
throw new ArrayIndexOutOfBoundsException(index);
}
}
步骤 3 根据元素删除
如果上面的方法理解了,那么这个方法简直就是soEasy,不就是遍历一遍数组的所有元素,然后重新调用上面的方法么?
说干就干。
public Object remove(Object e){
for (int i = 0; i < size; i++) {
if(array[i].equals(e)){
remove(i);
}
}
return true;
}
步骤 4 问题1
第一个问题,假如我给ArrayList添加null咋办?
如果元素是null,那么这个地方直接.equals肯定会报空指针的。所以,代码需要优化一下。
public Object remove(Object e){
for (int i = 0; i < size; i++) {
if(array[i] != null && array[i].equals(e)){
remove(i);
}
}
return true;
}
这边用了短路与,必须左边的表达式为true,右边的才会执行。
步骤 5 问题1–如何元素值为null怎么办?
第一个问题,假如我给ArrayList添加null咋办?
如果元素是null,那么这个地方直接.equals肯定会报空指针的。所以,代码需要优化一下。
public Object remove(Object e){
for (int i = 0; i < size; i++) {
if(array[i] != null && array[i].equals(e)){
remove(i);
}
}
return true;
}
这边用了短路与,必须左边的表达式为true,右边的才会执行。
步骤 6 问题2–怎么总是返回true
这个问题非常明显,就是return的地方很明显错了,改一下:
public Object remove(Object e){
for (int i = 0; i < size; i++) {
if(array[i] != null && array[i].equals(e)){
remove(i);
return true;
}
}
return false;
}
步骤 7 问题3–如果remove传进来的值是null?
如果remove传进来的值是null?还真有这种可能,虽然在当前的逻辑下,最多就是循环一圈找不到匹配的,返回false。但是,这样还是很影响效率,不如一开始就把这个情况判断掉。
public Object remove(Object e){
if(e == null)
return false;
for (int i = 0; i < size; i++) {
if(array[i] != null && array[i].equals(e)){
remove(i);
return true;
}
}
return false;
}
步骤 8 问题4–凭什么你可以添加null,还不允许我拿null去比较了?
额,好像也有道理,那就允许比较。。。
public Object remove(Object e){
if(e == null){
for (int i = 0; i < size; i++) {
if(array[i] == null){
remove(i);
return true;
}
}
}else{
for (int i = 0; i < size; i++) {
if(array[i] != null && array[i].equals(e)){
remove(i);
return true;
}
}
}
return false;
}
步骤 9 问题5–呵呵了,明知道不可能越界,你还要去一遍遍检查?
这个说到点子上了,因为我们是直接去循环数组的,不可能发生越界,所以,这边直接调用 remove(int index) 其实很耗费性能的。
改一下吧,不妨弄个fastRemove方法,跳过边界检查并且不返回删除元素值。
private void fastRemove(int index){
System.arraycopy(array, index+1, array, index, size - index -1);
array[–size] = null;
}
于是,代码就变成了这样:
public Object remove(Object e){
if(e == null){
for (int i = 0; i < size; i++) {
if(array[i] == null){
fastRemove(i);
return true;
}
}
}else{
for (int i = 0; i < size; i++) {
if(array[i] != null && array[i].equals(e)){
fastRemove(i);
return true;
}
}
}
return false;
}
最后给出一些测试用例,验证ArrayList的稳定性和可行性。
步骤 1 新增测试
public static void main(String[] args) {
TuziArrayList list = new TuziArrayList();
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println(list);
}
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
测试结果:通过!
#####步骤 2 删除测试
public static void main(String[] args) {
TuziArrayList list = new TuziArrayList();
for (int i = 0; i < 20; i++) {
list.add(i);
}
list.add(null);
list.add(“ABC”);
//1.根据下标删除
list.remove(10);
//2.根据参数对象删除
list.remove(new Integer(11));
//3.删除null
list.remove(null);
System.out.println(list);
}
0,1,2,3,4,5,6,7,8,9,12,13,14,15,16,17,18,19,ABC
测试结果:通过!
步骤 3 百万级数据压测
public static void main(String[] args) {
long startTime = System.currentTimeMillis(); //获取开始时间
TuziArrayList list = new TuziArrayList();
for (int i = 0; i < 100 * 10000; i++) {
list.add(i);
}
long overTime = System.currentTimeMillis();
System.out.println(“程序运行时间为:”+(overTime-startTime)+“毫秒”);
}
程序运行时间为:271毫秒
PK原生的ArrayList:
public static void main(String[] args) {
long startTime = System.currentTimeMillis(); //获取开始时间
List list = new ArrayList();
for (int i = 0; i < 100 * 10000; i++) {
list.add(i);
}
架构学习资料
由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
rTime-startTime)+“毫秒”);
}
程序运行时间为:271毫秒
PK原生的ArrayList:
public static void main(String[] args) {
long startTime = System.currentTimeMillis(); //获取开始时间
List list = new ArrayList();
for (int i = 0; i < 100 * 10000; i++) {
list.add(i);
}
架构学习资料
[外链图片转存中…(img-Jp3A80PW-1715568788416)]
[外链图片转存中…(img-a0uVgQfV-1715568788416)]
[外链图片转存中…(img-ZYPPbPmK-1715568788416)]
[外链图片转存中…(img-PVHMCHGM-1715568788417)]
[外链图片转存中…(img-m2j0I1zZ-1715568788417)]
由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!