更新时间:2016-08-17
百度视频面试
岗位:Java后台开发,Linux运维,数据库开发,缓存等工作
1、简单的自我介绍。
磕磕绊绊。
2、面试内容
看到这个问题,我一眼就知道答案是“郭美美”,但是在回答为什么是这个答案的时候,却不知道如何说出来。
值传递指的是在方法调用时,传递的参数是按值的拷贝传递。引用传递指的是在方法调用时,传递的参数是变量所对应的内存空间的地址。
值传递和引用传递的区别:对象被值传递其实是传递了对象的一个副本,所以对副本做任何修改都不会反映到源对象上。实参把他的值传递给形参,形参利用实参的值初始化一个临时的存储单元,虽然形参和实参值相同,但却是不同的存储单元,基本数据类型是值传递。
对象的引用传递传递的是一个引用,这个引用是指向源对象的,所以对引用对象的改变会反映到源对象上。传递给形参的值是地址,此时实参和形参指向同一地址单元,形参的改变会影响实参,除基本数据类型之外的其他数据类型使用引用传递。
PS:什么情况呢?
String 并不是基本数据类型,基本数据类型:第一类:整型 byte short int long;第二类:浮点型 float double;第三类:逻辑型 boolean(它只有两个值可取true false);第四类:字符型 char
String类是final修饰的,不可变,它会在内存中在开辟一块新空间。
3、String和StringBuffer以及StringBuilder。
提到了String,那么String和StringBuffer以及StringBuilder有什么区别呢?
Java中的String是一个类,而并非基本数据类型。string是值传入,不是引用传入。
- String 字符串常量 JDK1.0
- StringBuffer 字符串变量(线程安全) JDK1.0
- StringBuilder 字符串变量(非线程安全) JDK1.5
StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
单线程运行效率: String<< StringBuffer< StringBuilder
非线程安全:StringBuilder
线程安全:StringBuffer
单线程最佳:StringBuilder
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
4、String类型的常用于文件读写,那么
个人认为:
- 如何读取所有txt文件——读取目录的txt文件名;再依次读取txt文件内容
- 如何筛选出电子邮箱——正则表达式
- 如何保存到email.txt——写入文件
代码如下:
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
private static List<String> txtfilepath = new ArrayList<String>();
private static List<String> emailresult = new ArrayList<String>();
/*
* 递归调用遍历目录及其子目录下的所有txt文件并保存至列表中
*/
public static void GetTxtFilePath(File path) throws IOException {
if (!path.isDirectory()) {
System.out.println("文件目录不存在!");
} else {
File[] files = path.listFiles(); // 该文件目录下文件全部放入数组
if (files != null) {
for (int i = 0; i < files.length; i++) {
String filename = files[i].getName();
//判断是文件夹还是文件,遍历读取txt文件
if (files[i].isDirectory()) {
GetTxtFilePath(files[i]);
} else if (files[i].isFile() && files[i].getAbsolutePath().endsWith(".txt")) {
System.out.println(files[i].isFile() + " " + files[i].getAbsolutePath());
txtfilepath.add(files[i].getAbsolutePath());
}
}
}
}
}
/*
* 依次读取txt文件的内容,正则表达式匹配电子邮箱
*/
public static void ReadTxtFile(List<String> txtfilepath)throws IOException{
for (int i = 0; i < txtfilepath.size(); i++) {
String path = txtfilepath.get(i);
System.out.println(path);
BufferedReader bufferedReader = null;
//电子邮箱正则表达式
String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
Pattern p = Pattern.compile(check);
//读数据
try {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String str = null;
while ((str = br.readLine()) != null) {
Matcher m = p.matcher(str);
while (m.find()) {
emailresult.add(m.group());
}
}
br.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
/*
* 匹配结果写入email.txt
*/
public static void WriteResultFile(String resultfilepath)throws IOException{
FileWriter writer = new FileWriter(resultfilepath);
BufferedWriter bWriter = new BufferedWriter(writer);
for (int i = 0; i < emailresult.size(); i++) {
String str = emailresult.get(i);
bWriter.write(str);
bWriter.newLine();
}
bWriter.close();
}
public static void main(String[] args) {
File path = new File("d:/aa");
File resultpath = new File("d:/aa/email.txt");
try {
GetTxtFilePath(path);
ReadTxtFile(txtfilepath);
WriteResultFile(resultpath.getAbsolutePath());
} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();}
}
for (int i = 0; i < emailresult.size(); i++) {
System.out.println(emailresult.get(i));
}
}
}
磨磨蹭蹭地终于写完了,整理了下思路,这就是考察递归查找,文件操作,以及正则表达式的运用,当时的自己蒙圈了,还是基础知识没打牢。
5、打印出来的顺序是什么呢?
自己又蒙圈了,关于类的初始化和对象的初始化,那个在前哪个在后呢?
输出结果:
父类的静态初始化块
子类的静态初始化块
父类的初始化块
父类的构造方法
子类的初始化块
子类的构造方法
为什么是这样呢?
JVM初始化的原理
对象的初始化顺序:(java类加载器加载类的顺序:)
(1)加载父类(以下序号相同,表明初始化是按代码从上到下的顺序来的)
1.为父类的静态属性分配空间并赋于初值
2.执行父类静态初始化块;
(2)加载子类
1.为子类的静态属性分配空间并赋于初值
2.执行子类的静态的内容;
(3)加载父类构造器
1.初始化父类的非静态属性并赋于初值
2.执行父类的非静态代码块;
3.执行父类的构造方法;
(4)加载子类构造器
1.初始化子类的非静态属性并赋于初值
2.执行子类的非静态代码块;
3.执行子类的构造方法.
总之一句话,静态代码块内容先执行(父先后子),接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
静态代码块也只执行一次
5、有关于ArrayList
- a) ArrayList是List接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
b) ArrayList() 构造一个初始容量为 10 的空列表。
ArrayList(int initialCapacity)构造一个具有指定初始容量的空列表。
PS:
StringBuffer()构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。
StringBuffer(int capacity) 构造一个不带字符,但具有指定初始容量的字符串缓冲区。HashMap() 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity) 构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity, float loadFactor)构造一个带指定初始容量和加载因子的空 HashMap。HashSet() 构造一个新的空集合,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
HashSet(int initialCapacity) 构造一个新的空集合,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
HashSet(int initialCapacity, float loadFactor) 构造一个新的空集合,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。c) ArrayList() 构造一个初始容量为 10 的空列表。每次增容是以前的1.5倍左右,也就是每次增加一半。
- d) i. 优点是:查询效率高。ii. 缺点是:随机增删元素效率低。
6、HashSet和HashMap有什么关系?
- HashSet底层是采用HashMap实现的。
public HashSet() {
map = new HashMap<E,Object>();
}
- 调用HashSet的add方法时,实际上是向HashMap中增加了一行(key-value对),该行的key就是向HashSet增加的那个对象,该行的value就是一个Object类型的常量。
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
7、写出GC你所知道的算法
1.引用计数法:
通过引用计算来回收垃圾。
基本思想:有一个对象的引用计数器来计数一个对象被引用的次数,当一个对象每被引用一次,所对应的引用计数器的计数就会加一,每被释放一次,他的引用计数器的计数就会减一.当引用计数器的计数为零时,表示该对象未被引用.
引用计数法的问题:
a.引用和去引用伴随加法和减法,影响性能.
b.很难处理循环引用.当出现以下情况时,右侧3个无用的循环对象会一直占据着空间而不能被释放,因为他们的引用计数都不为零.
2.标记-清除
标记-清除算法是现代垃圾回收算法的思想基础.标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段.一种可行的实现,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象.因此,未被标记的对象就是未被引用的垃圾对象.然后,在清除阶段,清除所有未被标记的对象.
3.标记-压缩
标记压缩算法适用于存活对象较多的场合,如老年代.它在标记-清除算法的基础上做了一些优化.和标记-清除算法一样,标记-压缩算法也首先要从根节点开始,对所有的可达对象做一次标记.但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端.之后,清理边界外的所有空间.
4.复制算法
a.与标记-清除算法相比,复制算法是一种相对高效的回收方法.
b.不适用于存活对象较多的场合,如老年代.
c.将原有内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收.
存在的问题:空间浪费,整合标记清理思想.
分代思想: —–J2SE1.2以后使用此算法
一句对象的存活周期进行分类,短命的对象归为新生代,长命的对象归为老年代.
根据不同代的特点,选取合适的收集算法
a.少量对象存活,适合复制算法
b.大对象存活,适合标记清理或者标记压缩.
GC算法总结:
引用计数-没有被java使用.
标记-清除/标记-压缩被使用.其中新生代使用复制算法.
8、哪些类有serialVersionUID属性,该属性的作用是什么?
通常在继承 Serializable 接口的类
- ArrayList有该属性。作用是无论该类是否升级,是否发生源码的变动,只要该属性值一样,则代表是同一个版本的类。
9、软件设计常用原则
一.开-闭原则(Open-Closed Principle, OCP)
二.里氏代换原则(Liskov Substitution Principle,LSP)
三.依赖倒转原则(【Dependence Inversion】DIP)
四.接口隔离原则(【Interface Segregation Principle】 ISP)
无.合成/聚合复用原则(【Composite/Aggregate Reuse Principle】 或CARP)
六.迪米特法则(Law of Demeter LoD)
七.单一职责原则(Simple responsibility pinciple SRP)
10、Servlet是单实例多线程,还是多实例多线程?
- Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间。
10、JSTL标签在客户端执行还是在服务器端执行?
- jstl的标签会转化为服务器端的代码执行,而js代码则在客户端执行。
11、JDBC编程步骤?
- a) 注册驱动 Class.forName(“com.mysql.jdbc.Driver”)
- b) 获取连接 Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
- c) 获取数据库操作对象Statement stmt = conn.createStatement();
- d) 执行SQL语句ResultSet rs = stmt.executeQuery(“SELECT user_name, age FROM imooc_goddess”);
- e) 处理结果集 while (rs.next()) { }
- f) 释放资源 rs.close();stmt.close(); con.close();
12、Statement和PrepareStatement区别?
Statement执行一条sql就得编译一次,PrepareStatement只编译一次;常用后者原因在于参数设置非常方便;执行一条sql就得编译一次,后者只编译一次;还有就是sql放置的位置不同; 常用后者原因在于参数设置非常方便;
13、MySQL常用引擎?
- Myisam
- BDB
- Memory
- InnoDB
- Archive
MyISAM:默认的MySQL插件式存储引擎,它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一
InnoDB:用于事务处理应用程序,具有众多特性,包括ACID事务支持。
Memory:将所有数据保存在RAM中,在需要快速查找引用和其他类似数据的环境下,可提供极快的访问。
Merge:允许MySQL DBA或开发人员将一系列等同的MyISAM表以逻辑方式组合在一起,并作为1个对象引用它们。对于诸如数据仓储等VLDB环境十分适合。
14、MySQL分页语句?
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)
15、MySQL数据库函数?
MySQL函数包括数学函数、字符串函数、日期和时间函数、条件判断函数、系统信息函数、加密函数、格式化函数等。
- ABS(X):返回X的绝对值
- MOD(N,M)或%:返回N被M除的余数
- FLOOR(X):返回不大于X的最大整数值
- CEILING(X):返回不小于X的最小整数值
ROUND(X) :返回参数X的四舍五入的一个整数
ASCII(str):返回字符串str的最左面字符的ASCII代码值。
- CONCAT(str1,str2,…):返回来自于参数连结的字符串。如果任何参数是NULL,返回NULL。可以有超过2个的参数。一个数字参数被变换为等价的字符串形式。
- LENGTH(str):返回字符串str的长度。
- LOCATE(substr,str):返回子串substr在字符串str第一个出现的位置,如果substr不是在str里面,返回0.
- LEFT(str,len):返回字符串str的最左面len个字符。
SUBSTRING(str,pos):从字符串str的起始位置pos返回一个子串。
DAYOFWEEK(date):返回日期date的星期索引(1=星期天,2=星期一, …7=星期六)。
CASE value WHEN [compare-value] THEN result [WHEN [compare-value]
THEN result …] [ELSE result] END CASE WHEN [condition] THEN result
[WHEN [condition] THEN result …] [ELSE result] END 在第一个方案的返回结果中,
value=compare-value。而第二个方案的返回结果是第一种情况的真实结果。如果没有匹配的结果值,则返回结果为ELSE后的结果,如果没有ELSE部分,则返回值为 NULL。
SELECT CASE 11 WHEN 1 THEN ‘one’ WHEN 2 THEN ‘two’
ELSE ‘more’ END; SELECT CASE WHEN 1>0 THEN ‘true’ ELSE ‘false’ END;CONNECTION_ID()函数返回服务器的连接数,也就是到现在为止MySQL服务的连接次数;
PASSWORD(str)函数可以对字符串str进行加密。
FORMAT(x,n)函数可以将数字x进行格式化,将x保留到小数点后n位。这个过程需要进行四舍五入。
PS:太多了,一般配合SELECT使用,显示结果。
16、MySQL连接查询语句?
内连接:把两个表中数据对应的数据查出来
外连接:以某个表为基础把对应数据查出来
内连接(查找条件中对应的数据) inner join
左连接(左表中所有数据,右表中对应数据) left join
右连接(右表中所有数据,左表中对应数据) right join
SELECT stu.id,stu.name,stu.classe_name,tech.id,tech.name FROM stu INNER JOIN tech on stu.classe_name=tech.classe_name;
SELECT stu.id,stu.name,stu.classe_name,tech.id,tech.name FROM stu LEFT JOIN tech on stu.classe_name=tech.classe_name;
SELECT stu.id,stu.name,stu.classe_name,tech.id,tech.name FROM stu RIGHT JOIN tech on stu.classe_name=tech.classe_name;
17、Spring默认实现AOP方式,有什么限制?
Spring默认采用动态代理机制实现AOP,当动态代理不可用时(代理类无接口)会使用Cglib机制。
使用spring的AOP缺点:
a、只能对方法进行切入,不能对接口、属性、静态代码块进行切入(切入接口的某个方法,则该接口下所有实现类的该方法将被切入)
b、同类中的互相调用方法将不会使用代理类。因为要使用代理类必须从spring容器中获取bean。
获取代理类,如:
public IMsgFilterService getThis() {
return (IMsgFilterService)AopContext.currentProxy();
}
18、动态代理?
1.什么是动态代理?
答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。
2.为什么使用动态代理?
答:因为动态代理可以对请求进行任何处理
3.使用它有哪些好处?
答:因为动态代理可以对请求进行任何处理
4.哪些地方需要动态代理?
答:不允许直接访问某些类;对访问要做特殊处理等
19、1+2+3+…+100 不用for循环
递归:
public class sum1to100 {
public static int sum(int n){
int sum = 0;
if(n == 0)
return 0;
return sum(n-1)+n;
}
public static void main(String[] args){
int n = 100;
System.out.print(sum(100));
}
}
20、Linux 查找a.txt中字符串“abcdefg”
grep 功能说明:查找文件里符合条件的字符串。
grep ‘abcdefg’ a.txt
PS:如何查看tomcat的进程呢?
linux下查看tomcat进程命令为:ps aux | grep tomcat
名称:ps
使用权限:所有使用者
使用方式:ps [options] [–help]
说明:显示瞬间行程 (process) 的动态
参数:ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义
-A 列出所有的进程
-w 显示加宽可以显示较多的资讯
-au 显示较详细的资讯
-aux 显示所有包含其他使用者的行程
管道符“|”,这个符号可以将一个命令的标准输出管道为另外一个命令的标准输入
21、rpc的框架 知道哪些?
RPC, 远程过程调用直观说法就是A通过网络调用B的过程方法。
常见的RPC框架有:thrift,Finagle,dubbo,grpc,json-rpc等
22、WebService用过吗?
1.Axis2
Axis是apache下一个开源的webservice开发组件,出现的算是比较早了,也比较成熟。
2.Apche CXF
CXF开发webservice也是比较方便和简单的,它和spring的集成可以说是非常地好。
3.JDK开发webservice
4.xfire
23、了解SOAP?
SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。
SOAP 提供了一种标准的方法,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。
24、常用的解析json的开源组件?
目前主流进行JSON解析的开源库主要有Fastjson、Jackson、Gson等,
Gson是Google发布的一个开源Java类库,能够很方便的在Java对象和JSON字符串之间进行序列化和反序列化。
fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。
25、jsp 内置对象有哪些?
9大内置对象
Request,Response,Out,Session,Application,Cookie,Config,Page,Exception