将自己遇到的有含量且常见的面试题分类统计
-----------------------linux相关------------------------
在这里总结自己面试这么多次遇到的linux相关的面试题:
1.linux启动过程是咋样的?
大致分为五步:
(1)内核引导:
读入/boot下的内核文件
(2)运行init
读取/etc下面的配置文件(init进程)
(3)系统初始化:
读取/etc/rc.d/rcX.d/目录下面的文件 (开机启动的一些服务)
[root@iz2ze46xi6pjjj69ailg9lz bin]# cd /etc/rc.d/[root@iz2ze46xi6pjjj69ailg9lz rc.d]# lsinit.d rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d rc.local
/etc/rc[0-6].d是/etc/rc.d/rc[0-6].d的软连接: /etc/init.d是/etc/rc.d/init.d的一个软连接
(4)建立终端:
建立6个终端 tty1-tty6
(5)用户登录
三种登录方式:
ssh 命令行 图形化界面
2.linux的文件权限以及如何改变文件权限?
(1)文件权限解释:
首先看一组linux文件权限:
[root@iz2ze46xi6pjjj69ailg9lz ~]# lltotal 307576-rw-r--r-- 1 root root 356682 Mar 14 23:40 ~-rw-r--r-- 1 root root 8961394 Feb 1 15:59 exam1.31.sql-rw-r--r-- 1 root root 14744393 Jan 27 13:50 exam.sql-rw-r--r-- 1 root root 213608341 Jan 27 22:19 Exam.wardrwxrwxr-x 11 17608 17608 4096 Aug 22 2017 mbedtls-2.6.0-rw-r--r-- 1 root root 1958070 Mar 14 23:53 mbedtls-2.6.0-gpl.tgz-rw-r--r-- 1 root root 75281701 Mar 26 22:02 mongodb-linux-x86_64-3.2.9.tgzdrwxr-xr-x 3 root root 4096 Mar 14 23:46 ss-rw-r--r-- 1 root root 40 Sep 1 2017 testdrwxr-xr-x 3 root root 4096 Jan 26 20:51 tomcat项目drwxr-xr-x 2 root root 4096 Oct 28 10:51 wwdrwxr-xr-x 3 root root 4096 Dec 16 16:48 自己的练习
在Linux中第一个字符代表这个文件是目录、文件或链接文件等等。
- 当为[ d ]则是目录
- 当为[ - ]则是文件;
- 若是[ l ]则表示为链接文档(link file);
- 若是[ b ]则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
- 若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。
接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合。其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。
r=读取属性 //值=4
w=写入属性 //值=2 x=执行属性 //值=1
(2)改变文件的运行权限: chmod 命令:
权限范围的表示法如下:
u
User,即文件或目录的拥有者;
g
Group,即文件或目录的所属群组;o
Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围;a
All,即全部的用户,包含拥有者,所属群组以及其他用户;r
读取权限,数字代号为“4”;
写入权限,数字代号为“2”;x
执行或切换权限,数字代号为“1”;-
不具任何权限,数字代号为“0”;s
特殊功能说明:变更文件或目录的权限。
chmod(选项)(参数)
选项
-c或——changes:效果类似“-v”参数,但仅回报更改的部分;-f或--quiet或——silent:不显示错误信息;-R或——recursive:递归处理,将指令目录下的所有文件及子目录一并处理;-v或——verbose:显示指令执行过程;--reference= <参考文件或目录> :把指定文件或目录的所属群组全部设成和参考文件或目录的所属群组相同; <权限范围> + <权限设置> :开启权限范围的文件或目录的该选项权限设置; <权限范围> - <权限设置> :关闭权限范围的文件或目录的该选项权限设置; <权限范围> = <权限设置> :指定权限范围的文件或目录的该选项权限设置; 权限设置> 权限范围> 权限设置> 权限范围> 权限设置> 权限范围> 参考文件或目录>
参数
权限模式:指定文件的权限模式;
文件:要改变权限的文件。
例子:
chmod u+x,g+w f01 //为文件f01设置自己可以执行,组员可以写入的权限chmod u=rwx,g=rw,o=r f01chmod 764 f01chmod a+x f01 //对文件f01的u,g,o都设置可执行属性
文件的属主和属组属性设置
chown user:market f01 //把文件f01给uesr,添加到market组ll -d f1 查看目录f1的属性
3.如何设置一个服务开机启动?
开机服务自启动就是将一可执行文件放到/etc/init.d/目录下,并在/etc/rc.d/rc[0-6].d或者/etc/rc[0-5].d目录下创建软连接。
/etc/rc[0~6].d其实是/etc/rc.d/rc[0~6].d的软连接,主要是为了保持和Unix的兼容性才做此策
- 创建可执行脚本文件
- 赋予文件运行权限
chmod +x XXX.sh
- 创建软连接
可以手动创建软连接或者chkconfig创建连接。
(1)手动在rc[0-6].d创建软连接:
在rc0.d-rc6.d目录下分别创建文件连接。
第一个字符是S,系统在启动的时候,运行脚 本test2,就会添加一个start参数,告诉脚本,现在是启动模式。同时在rc0.d和rc6.d目录下,创建名字为K90test2的 文件连接,第一个字符为K,系统在关闭系统的时候,会运行test2,添加一个stop,告诉脚本,现在是关闭模式。
ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc2.d/S99test2ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc3.d/S99test2ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc5.d/S99test2ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc0.d/K01test2ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc6.d/K01test2
(2)chkconfig创建软连接:
chkconfig --add test2
脚本的前三行如下:(脚本前面三行格式固定)
#!/bin/sh#chkconfig: 2345 80 90#description:test2
第一行,告诉系统使用的shell,所有的shell脚本都是这样。
第 二行,chkconfig后面有三个参数2345,80和90告诉chkconfig程序,需要在rc2.d~rc5.d目录下,创建名字为 S80test2的文件连接,连接到/etc/rc.d/init.d目录下的的test2脚本。
验证服务:
chkconfig --list
参考:
4.linux的运行级别是咋样的?
5.linux下面想要查询一个日志文件的最后20行
head,tail分别显示文件开头和结尾内容
例如查看文件前20行:
head -n 20 xxx.txt
查看文件最后20行
tail -n 20 xxx.txt
查看文件中间一段,你可以使用sed命令,如:
sed -n '8,9p' catalina.2018-03-15.log
这样你就可以只查看文件的第8行到第9行。
如果需要实时查看日志:
tail -f catalina.out
6.linux的shell类型
sh(全称 Bourne Shell): 是UNIX最初使用的 shell,而且在每种 UNIX 上都可以使用。Bourne Shell 在 shell 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种 shell。bash(全称 Bourne Again Shell): LinuxOS 默认的,它是 Bourne Shell 的扩展。与 Bourne Shell 完全兼容,并且在 Bourne Shell 的基础上增加了很多特性。可以提供命令补全,命令编辑和命令历史等功能。它还包含了很多 C Shell 和 Korn Shell 中的优点,有灵活和强大的编辑接口,同时又很友好的用户界面。csh(全称 C Shell): 是一种比 Bourne Shell更适合的变种 Shell,它的语法与 C 语言很相似。Tcsh: 是 Linux 提供的 C Shell 的一个扩展版本。Tcsh 包括命令行编辑,可编程单词补全,拼写校正,历史命令替换,作业控制和类似 C 语言的语法,他不仅和 Bash Shell 提示符兼容,而且还提供比 Bash Shell 更多的提示符参数。ksh (全称 Korn Shell): 集合了 C Shell 和 Bourne Shell 的优点并且和 Bourne Shell 完全兼容。pdksh: 是 Linux 系统提供的 ksh 的扩展。
7.Linux开放端口
/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
最后可以加个 service iptables save 永久保存
---------------------Java基础相关--------------------
0.Java所有的new操作都是在堆中创建对象,Java的下标除了JDBC获取结果集从1开始,基本上所有的下标都是从0开始。
1.static关键字的用法:(从五方面解释)
- 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
- 用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
- 静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键)
可以用于处理只执行一次的代码,例如:hibernate种SessionFactory的创建,mybatis的SqlSessionFactory的创建
- 静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。
import static java.lang.System.out;
out.println(HibernateUtils.openSession());
- 静态内部类 用法
2.Java中final,finally,finalize的区别
(1)final可以修饰类、方法、变量
- 修饰类表示类不可以被继承
- 修饰方法表示此方法不可以被重写(覆盖)但是可以被重载
- 修饰变量表示变量不可变(引用不可变--也就是不可以重新指向另一个对象,但是引用内容可以变),而且static final 经常用作常量处理。
(2)finally的使用:---通常用于try..catch..之后关闭一些IO流等操作
-
try语句没有被执行,如在try语句之前就返回了,这样finally语句就不会执行;因此说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。
-
如果在try代码块中执行System.exit(0)语句;那么将终止Java虚拟机JVM,因此,finally语句也不会被执行到。
-
finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,如果返回值类型为传址类型(String与8种包装类型除外),则影响;传值类型与String与8种基本数据类型的包装类型,则不影响。若finally里也有return语句则覆盖try或catch中的return语句直接返回。
package cn.qlq.test;public class FinallyTest { public static void main(String[] args) { System.out.println(test1()); System.out.println(test2()); } public static String test1() { String s = "s1"; try { int i = 1 / 0; s = "s2"; return s; } catch (Exception e) { s = "s3"; return s; } finally { s = "s4"; } } public static Person test2() { Person p = new Person(); p.setName("old"); try { int i = 1 / 0; return p; } catch (Exception e) { p.setName("exception"); return p; } finally { p.setName("finally"); } }}
结果:
s3
Person [age=0, name=finally]
finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,如果返回值类型为传址类型,则影响;传值类型(8种基本类型)与8种基本数据类型的包装类型与String(不可变类)不影响。若finally里也有return语句则覆盖try或catch中的return语句直接返回。
面试宝典解释的原因如下:
程序在执行到return时首先会把返回值存到一个指定的位置(JVM中的slot),其次与执行finally块,最后再返回。如果finally中有return语句会以finally的return为主,相当于普通程序中的return结束函数。如果没有return语句,则会在finally执行完之后弹出slot存储的结果值并且返回,如果是引用类型则finally修改会影响结果,如果是基本数据类型或者不可变类不会影响返回结果。
(3)finalize()析构方法的使用
finalize()在JVM回收对象的时候会调用该对象的此方法,用于垃圾回收的时候处理一些事情
3.switch支持的数据类型:
记住一条,可以转为int型的都可以作为switch case的数据类型,switch表达式后面的数据类型只能是byte(1),short(2),char(2),int(4)四种整形类型(这些基本类型的包装类型是不支持的),枚举类型和java.lang.String类型(从java 7才允许),不能是boolean类型。
4.java基本数据类型的长度以及数据类型转换以及初值
Java一共提供了8种原始的数据类型(byte、short、int、long、float、double、char、boolean),这些数据类型不是对象,而是Java中不同于类的特殊类型,这些基本类型的数据变量在声明之后就会立即在栈上被分配空间。除了这些基本类型外,其他类型都是引用类型,这类变量在声明时不会被分配内存空间,只是存储了一个内存地址。
注意:
1) 在Java中,默认声明的小数是double类型的,而整数默认是int类型。
2) 在Java中,null不是一个合法的Object实例,所以编译器并没有为其分配内存,它仅仅用于表明该引用目前没有指向任何对象。null是将引用变量的值全部置0。
注意:如果是临时变量(方法内部变量)不会赋初值,只有成员属性才会赋初值。
5.java多态----覆盖(重写概念)
覆盖就是父类的变量指向子类的对象,调用变量的方法实际上是调用子类的覆盖了父类的方法,这也是多态的体现(面试官说重写是多态,重载是不是还在研究中。。。。。。。)。
Parent p1 = new Child1(); Parent p2 = new Child2(); p1.method1();//调用Child1类重写了父类的method1方法 p2.method1();//调用Child2类重写了父类的method1方法
多态的三个必要条件:
- 继承
- 重写
- 父类引用指向子类对象
多态的实现方式:
重写、接口、抽象方法和抽象类
6 .java异常
Error和Exception(运行时异常和检查异常) 参考
7.Java的Integer常量池和String常量池
String s1 = new String("1"); 是在堆中创建一个String对象,并将s1指向该对象;String s2 = new String("1"); 又在堆中创建一个String对象,并将s2指向该对象;
String s3 = "1"; 在常量池创建一个对象1,并将s3指向该对象;String s4 = "1" 的时候常量池已经有1,所以不会再创建对象,也就是s3与s4指向同一个对象。
Integer i1 = new Integer(1)的时候是在Java堆中创建一个Integer对象,i1指向堆中的对象,i1与常量池没关系。
Integer i3=1;的时候是从常量池中查找值为1的常量,i3指向该常量,Integer常量池的大小是-128到127
8.深复制与浅复制区别
浅复制:被赋值的对象与原对象都含有相同的值,而所有对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅赋值所考虑的对象,而不复制它所引用的对象。
深赋值:被复制的对象的所有变量都有与原对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被赋值的新对象,而不再是原来的那些被引用的对象。换言之,深复制把复制的对象所引用的对象都复制了一遍。
9.值传递与引用传递
1)值传递:方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。
2)引用传递(指针传递):也称为传地址。方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,所以方法执行中形式参数的改变将会影响实际参数。(包装类型是引用传值,但是由于String和8种包装类型的不可变性,所以操作形参相当于重新创建对象并赋给形参,不影响实参),数组也是引用传递。
在Java中,原始数据类型在传递参数时都是按值传递,而包装类型在传递参数是是按引用传递,但包装类型在进行计算的时候会自动拆箱,。
对象在函数调用传参的时候是引用传递(基本数据类型值传递),"="赋值也是引用传递(基本数据类型值传递)
10.可变类与不可变类
不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String(8种基本数据类型的包装类和String都是不可变类)等。不可变类的意思是一旦这个对象创建之后其引用不会改变,每次重新赋值会新增一个对象。不可变类是实例创建后就不可以改变成员遍历的值。这种特性使得不可变类提供了线程安全的特性但同时也带来了对象创建的开销,每更改一个属性都是重新创建一 个新的对象。例如String s = "s1",s = "s2"实际上是创建了两个对象,第二次将其值指向新的"s2".。
可变类:相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类
11.创建对象的五种方式
---------------------Web前端相关-------------------------
1.JS闭包概念
---------------------JavaWeb相关-------------------------
---------------------数据结构相关--------------------------
---------------------数据库相关--------------------------
---------------------Java框架相关--------------------------
package cn.qlq.fina;/** * final 关键字使用 * @author Administrator * */public class TestCla { private static final int a = 1; private static final User u = new User();; public static void main(String[] args) { // a = 2;// final修饰的变量不可改变(引用不可变) // u=new User();//引用不可变,不可再指向其他对象,但是引用内容可以改变 u.setUsername("sssssss"); u.setUsername("XXXXXXX"); } public void test1(final int x ){// x=1;//final修饰的变量不可改变,方法上的形参也不可以变 }}
2.finally的使用:---通常用于try..catch..之后关闭一些IO流等操作
-
try语句没有被执行,如在try语句之前就返回了,这样finally语句就不会执行;因此说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。
-
如果在try代码块中执行System.exit(0)语句;那么将终止Java虚拟机JVM,因此,finally语句也不会被执行到。
-
finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,如果返回值类型为传址类型,则影响;传值类型,则不影响。若finally里也有return语句则覆盖try或catch中的return语句直接返回。
测试代码:
package cn.qlq.test;/** * * @author Administrator * */public class MyTest { public static final int i = 6; @SuppressWarnings("finally") public static long test1() { String val = "5d"; long value = 5; try { value = Long.parseLong(val); } catch (NumberFormatException e) { System.out.println("catch..."); return value++; } finally { System.out.println("finally..."); value--; return value; } } public static void main(String[] args) { System.out.println(MyTest.test1()); }}
结果:
catch...finally...5
3.finalize()析构方法的使用
finalize()在JVM回收对象的时候会调用该对象的此方法,用于垃圾回收的时候处理一些事情。
package cn.qlq.test;/** * * 测试finalize()方法,对象消亡的时候调用的方法,类似于C++的析构函数 * @author Administrator * */public class MyTest { public static final int i = 6; @Override protected void finalize() throws Throwable { System.out.println("对象要死亡"); } @SuppressWarnings("finally") public long test1() { String val = "5d"; long value = 5; try { value = Long.parseLong(val); } catch (NumberFormatException e) { System.out.println("catch..."); return value++; }finally { System.out.println("finally..."); value--; return value; } } public static void main(String[] args) { MyTest my = new MyTest(); System.out.println(my.test1()); my = null;//清空对象的引用,使其被垃圾回收 System.gc();//调用GC回收垃圾 }}
结果:
catch...
finally...5对象要死亡
昵称:
退出
[Ctrl+Enter快捷键提交]