写这篇文章的原因还要从去年这时候说起,话说小白已经下定决心考研,并且选取了非常明确的“目标”,从此走上了考研之路。小白是计算机专业的,但是学业上除了保持不挂科的记录,好像确实对本专业没什么了解,大学三年多不知道到底干了些啥,闲话短说,学习的时光过的总是漫长而迅速的,转眼就到了七月,结果家中发生了一件大事(具体原因暂不想说),这时候我刚放假没两天,本来跟家里人说准备考研暑假不回家的,听到消息的我当天订了机票回去。再回学校已是八月份,综合我多方面的考虑后,最终决定放弃考研这条路(其实主要是自己学的也不行,怕成陪考的哈哈)。之后就开始了我的漫漫学习java之路,我的路程是极为坎坷的,我不像有些大神,可能学了两个月后就已经精通了的那种。我这第一遍跟着王克学习了一遍基础,完全没感觉,就学会了一些while,for循环啥的。不仅如此,国庆七天乐我又开始放松了警惕,沉迷于某某荣耀。正好这时候我一个室友从北京实习完回来了,我们聊起了这件事,然后他就随便问了我几个面试问题,结果我一个答不出来,我伤心欲绝,第二天开始发奋学习,到了十一月,觉得自己的基础总算有所提升,室友给了我一本厚达四百多篇的xxJava面试宝典。完了,这一看不要紧,我发现在我这一遍又白学了,好家伙,这java为什么这么多东西哦,老子想着就有气。十二月中旬,秋招也正式结束了,学校的课程也上完了,考研也结束了,我们室友们一起吃了顿饭,就此各回各家,各干各的事。
回到家的前几天开始看面试宝典,总共打了三份不一样的面试宝典,加起来的页数足足有一千页,好了,这下又轮到我傻眼了。管他三七二十一,背就完了,然而。。。这他么根本不是背不背的说法啊,这完全看不懂啊!好了,我就强忍着看不懂的尴尬,一直往下看,看到没学过的技术,跳过,看到太麻烦的术语,跳过,看到像栈后进先出的特点,咦,学过,画一道横线,打个五角星,就当自己背过了。。。就这样一直到了我哥放假时候回来了,我的面试宝典早已一篇篇画红,但是仔细一看,问啥啥不会。先不管这些,我哥回来了,这下一下子有事情干了,就这样,某某荣耀愉快的陪伴了我十多天。
决定回老家了,是正月二十六晚上,我老家是河南的,因为自己家车坐不下,所以我坐的堂哥的车回去的,他一家人都很壮实,把我挤在后排中间难受的一批,不过挺挺就好了,七个小时后,我睡在了床上。睡醒后,回家的第一件事当然是大吃特吃,大玩特玩。呵呵,想什么呢,第一天当然是大扫除,这给我累的,一天灰头土脸的,穿的一件白色羽绒服变成了灰黑色。在家里网速不好,但这不能阻止我们打某某荣耀,愉快的几天过去了,结果疫情来了,越来越严重,我们闻风色变,再加上听闻要封高速,我妈怕回不去上班,所以我们连夜赶回杭州。(结果事情越来越严重,我妈到现在还没有能上班哈哈哈。)
年也过完了,是不是该消停了,是不是该找工作了?是,但是我不是,在疫情下,我越发感到空虚,一点学习的心思都没有,完全不知道该怎么办才好,这时候,某某荣耀又出来了,于是,沉沦的一个月,就不提了,中间间隔的时候量良心上过不去偶尔看看面试题,但是并没什么卵用。于是乎,继续开始学习,经过这几天的整理,我发现,我还是一个小白,最近也被毕业设计开题搞得很烦,于是乎,我下了一个决心,删掉某某荣耀,在春招结束前找到一份工作,(实在不行就只能找实习了),从今天开始,每天记录我的学习路径,以及每天准时到简书打卡。
废话说了这么多,怕被嫌弃,开始我今天的主题吧。我就是Java小白,开始第一天的阐述。我不是大神,想像大神学习的恳请一年后来我这哈哈哈,我只是一个连jvm的垃圾回收机制,ssm框架的搭建,MySQL的优化,Redis都不会,没有项目,没有工作经验的java小白。 (前言)
第一天正文
今天主要视频学习了一些简单的面试题,其中有很多我之前也会的,但是也会有忘的。用我的理解给大家讲一下,(过于简单请大佬绕行。。。)顺便加深以下我自己的印象,如果有理解不对的地方,和错误的地方,希望大家指正,我们一起学习,一起努力,一起摆脱学渣,小白的标签。
1.简单讲一下Java跨平台原理
java跨平台主要靠的是jvm(虚拟机java virtual machine),虚拟机相当于一个虚拟的带有硬件系统的电脑,java程序经过编译后会生成字节码文件(.class文件),虚拟机将这些字节码文件解释成对应的机器码语言便可实现跨平台特性,比如linux,windows,unix系统等。
2.Java的基本数据类型有几种?
Java的基本数据类型有8种。分别是byte,short,int,long,char,boolean,float,double。其中可能还会问到某个基本数据类型占几个字节。我是这样背的,short,int,long,char分别占1,2,4,8个字节;boolean,char,float,double各占1,2,4,8个字节。其中int为默认的整数类型,double为默认的的浮点数类型。还要注意的是定义float数的时候,定义的数后面要有一个F(大小写都可以),定义long类型的的整数时也要加上L(大小写均可)。比如 long l = 23L;
3.有了基本数据类型,为什么还要包装类型?
包装类是指每一个基本数据类型对应的包装类,其实就是所有基本数据类型第一个字母变成了大写,这就成了包装类,比如short ==> Short,但是,有两个是特殊的,int ==> Integer和char ==> Character。这两个需要单独记。那么为什么要包装类呢,因为Java是面向对象的语言,而基本的数据类型却是不具备面向对象的特性的。当有了包装类后,我们可以使用创建对象的方式使用包装类(new一个对象)。其中还涉及一个知识点,就是自动装箱和自动拆箱,自动装箱的意思就是自动把基本数据类型转换为对应的包装类。而自动拆箱则相反。自动装箱会调用Integer.valueOf方法,而自动拆箱会调用intValue方法。如:
Integer i = 1; //自动装箱(会自动把int类型的数转换为包装类Integer)
int j = i; //自动拆箱(会自动把包装类i转换为基本数据类型int)
4."=="和equals方法的区别
"=="用来判断两个变量之间的值是否相等,但是变量分为基本数据类型和引用数据类型(基本数据类型是指上面所讲的8种,而引用数据类型是指除上述之外的其他类型,如String),如果是基本数据类型“==”比较的是具体的值,而如果是引用数据类型则比较的是引用的内存的地址值。(有点类似c语言的指针)。equals主要用来判断两个对象的内容是否相同(如String类重写了equals方法比较的是连个字符串的内容是否一致)。
注:equals方法不能用于基本数据类型的变量,如果没有对equals方法重写,则比较的是引用类型的变量所指向的对象的地址值。
5.String、StringBuilder和StringBuffer的区别
1.String被设计为一个内容不可变的类,它的底层是一个final修饰的字符数组,StringBuilder和StringBuffer底层用的是内容可以改变的字符串(没有使用final修饰)。
2.String拼接字符串使用+来拼接,而StringBuilder和StringBuffer需要创建对象之后使用append方法追加字符串。
3.StringBuilder是线程不安全的,效率较高,StringBuffer是线程安全的,效率较低(只要是线程安全的效率都较低,线程不安全的效率都较高。涉及到synchronized关键字)。
6.讲一下Java中的集合
1.Java中集合主要包括两大类Collection(存储value单列数据)和Map(存储key-value双列数据)。
2.Collection主要包括两类List(存储数据有顺序,存储的值可以重复)和Set(存储数据没有顺序,不允许存储重复的值)。
3.Map中存储的数据是没有顺序的,它的键(key)不允许重复,值(value)可以重复。
注:一个对象要存储在Set集合中,一定要重写equals和hashCode方法。
7.ArrayList和LinkedList的区别
1.ArrayList底层是用的是数组,数组在内存中是一块连续的空间,因为有索引,所以查询速度比较快,而插入和删除需要移动内存,所以比较慢。
2.LinkedList底层采用的是链表,链表不要求存储的数据是连续的,但是会在当前元素存放·上一个或下一个元素的地址值。查询的时候需要从头部开始,一个一个的找,所以比较慢,而插入和删除时不需要移动内存,只需改变引用指向即可,所以插入和删除比较快。
总结:ArrayList使用在查询比较多,而插入和删除比较少的情况,而LinkedList正好相反。
8.HashMap和HashTable的区别
相同点:HashMap和HashTable都是用来存储key-value(键值对)数据的。
不同点:
1.HashMap的key和value可以存储null(空)值,而HashTable不可以。
2.HashMap是线程不安全的,所以效率较高,而HashTable是线程安全的,所以效率较低。
如果既想要线程安全,又想要效率高,可以使用ConcurrentHashMap集合。它的实现原理是:通过把Map分为N个segment(段),类似于HashTable,可以提供相同的线程安全,效率提升N倍。
9.实现一个拷贝工具使用字符流还是字节流?
因为我们不确定拷贝的是什么文件,如果只是单纯的拷贝文章类信息我们可以使用字符流,但是为了通用性(比如拷贝音乐,电影等),我们应当使用字节流。
10.线程的几种实现方式
1.通过继承Thread类,
2.通过实现Runnable接口,
通常我们都会使用实现Runnable接口的方法来实现一个线程,因为Java只支持单继承(但是可以多实现),如果这个类继承Thread类就不能再继承其他类了。
启动线程:调用start方法(调用start方法后的启动的是重写后的run方法)。
区分线程:可以使用setName方法设置线程名称,加以区分,一般在创建线程完成后,都需要设置名称。
11.线程池的作用
1.限制线程的个数,避免因线程过多而导致系统运行缓慢或崩溃。
2.不用每次去创建和销毁线程池,节约了资源。
3.不用每次去创建线程池,响应速度更快。
注:数据库连接池也类似。
12.get和post的区别
get和post请求都是http的请求方式,用户通过不同的请求方式可以完成对资源(url)的不同操作。GET,POST,PUT,DELETE分别对应着对这个资源进行查,改,增,删4个操作。GET一般用来查询资源信息,而POST一般用来更新资源信息。
区别:
1.get请求的数据会在地址栏上显示出来(请求的数据放在url之后,以?分割url和传输数据,多个参数用&连接),而post请求的数据会放在http包的包体中。
2.传输数据的大小限制。get请求由于浏览器对地址长度的限制而导致传输的数据有限制,而post请求不会因为这个原因而导致传输数据限制。(其实理论上没有长度限制,它的限制取决于操作系统的支持,只是一个说法而已)
3.post的安全性要高于get。由于get的数据会在地址栏中呈现,所以可以通过历史记录找到密码等关键信息。
13.什么是jsp?什么是Servlet?jsp与Servlet的区别
jsp本质上就是一个Servlet,它是Servlet的一种特殊形式,每个jsp页面都是一个Servlet实例.
Servlet(Java Server Applet)是用Java编写的服务器端程序,所有自定义的Servlet必须实现Servlet接口。其主要功能在于交互式的浏览和修改数据,生成动态Web内容。
区别:
1.jsp是html页面中内嵌的Java代码,侧重于视图(页面显示)。
2.Servlet是html代码和Java代码分离,侧重于控制逻辑。
3.mvc设计思想中jsp位于视图层,Servlet位于控制层。
14.http中重定向(redirect)和请求转发(foward)的区别
1.forward是服务器端的转向而redirect是客户端的转向。
2.使用forward浏览器的地址不会发生改变,而使用redirect会发生改变。
3.forward是在一次请求中完成,而redirect是重新发起请求(两次请求)。
4.forward是在服务器端完成,而不用客户端重新发起请求,效率较高。
15.Cookie和Session的区别
Cookie和Session都是会话(Session)跟踪技术。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。Session的实现依赖于Cookie和SessionId(Session的唯一标识,存放在客户端)。
区别:
1.Cookie数据存放在客户端的浏览器上,而Session数据存放在服务器上。
2.Cookie不是很安全,别人可以通过分析存放在本地的Cookie进行Cookie欺骗。考虑到安全性应当使用Cookie。
3.Session会在一定时间内保存到服务器上。当访问增多时,会比较占用服务器的性能能。考虑到减轻服务器性能方面我们应当使用Cookie。
4.单个Cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个Cookie。
建议将登录信息等重要信息存放在Session中,需要保留的信息如购物车可以存放在Cookie中。由于Cookie在客户端是可以禁用的,如果被禁用,我们可以使用Cookie+数据库的方式实现,当Cookie中取不到数据时,就从数据库中取。
16.jsp有哪些内置对象?有哪四大作用域?
内置对象有9个,包括:
1.request:用户端请求,此请求会包含来自get/post请求的参数。
2.response:服务器端对客户端的回应。
3.pageContexts:管理网页的属性。
4.session:与请求有关的会话期。
5.application:Servlet正在执行的内容。
6.out:在web浏览器内输出信息。
7.config:Servlet的构架部件。
8.page:jsp网页本身。
9.exception:显示异常信息。
四大作用域:pageContexts、request、session和application。,可以通过jstl从四大作用域中获取。
今日分享到此结束,快十二点了,该睡觉啦,明天又是元气满满的一天。