前言

参加了2017年校招,面试了阿里、百度、腾讯、滴滴、美团、网易、去哪儿等公司,个人是客户端 Android 方向,总结了面试过程中频率出现较高的题目,希望对大家有所帮助。

Java 一些知识点

Object 有哪些方法

  • public  方法: getClass 、 equals 、 hashCode 、 toString 、 wait 、 notify
  • protected  方法: clone 、 finalize
  • private  方法: registerNatives ,该方法作用是将不同平台C/C++实现的方法映射到Java中的 native 方法
public class Object {private static native void registerNatives();// 声明后有紧接静态代码块static {registerNatives();}
}

自动装箱

public static void main(String[] args) {int i = 0;Integer j = new Integer(0);System.out.println(j == i);System.out.println(j.equals(i));
}

上述代码的输出是

true
true

Java 虚拟机 GC 根节点的选择

Java通过可达性分析来判断对象是否存活。基本思想是通过一系列称为”GC roots”的对象作为起始点,可以作为根节点的是:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象

笔者这么理解,作为GC Roots的节点主要在全局性的引用(例如常量或类静态属性)与执行上下文(例如栈帧中的本地变量表)中。

虚拟机栈、本地方法栈这都是局部变量,某个方法执行完,某些局部使用的对象可以被回收。

类加载机制

  • 启动类加载器( Bootstrap ClassLoader)启动类加载器无法被 java 程序员 直接引用, 这个类加载器负责把存放在 <JAVA_HOME>\lib 目录中的, 或者被 -Xbootclasspath 参数指定路径中的, 并且是被虚拟机识别的类库加载到虚拟机内存中.
  • 扩展类加载器(Extension ClassLoader)负责加载在 <JAVA_HOME>\lib\ext 目录中的, 或者被 java.ext.dirs 系统变量所指定的路径中的所有类库。
  • 应用程序类加载器( Application ClassLoader )这个类加载器是 ClassLoader  中的  getSystemClassLoader() 方法的返回值, 一般称其为系统类加载器, 它负责加载用户类路径(  ClassPath  )上所指定的类库

从 java 虚拟机的角度而降, 只存在两种不同的类加载器:

  • 一个是启动类加载器(  Bootstrap ClassLoader  ), 这个类加载使用 C++ 语言实现, 是虚拟机自身的一部分;
  • 另一种是其他所有的类加载器, 他们由 java 语言实现, 独立于虚拟机之外, 并且全部继承自 java.lang.ClassLoader

加载类的寻找范围就是 JVM 默认路径加上 Classpath , 类具体是使用哪个类加载器不确定。

类加载主要步骤

  • 加载 把 class 文件的二进制字节流加载到 jvm 里面
  • 验证 确保 class 文件的字节流包含的信息符合当前 jvm 的要求 有文件格式验证, 元数据验证, 字节码验证, 符号引用验证等
  • 准备 正式为类变量分配内存并设置类变量初始值的阶段, 初始化为各数据类型的零值
  • 解析 把常量值内的符号引用替换为直接引用的过程
  • 初始化 执行类构造器 <clinit>() 方法
  • 使用 根据相应的业务逻辑代码使用该类
  • 卸载 类从方法区移除

双亲委派模型

除了顶层的启动类加载器之外, 其余的类加载器都应当有自己的父类加载器, 父子关系这儿一般都是以组合来实现。

工作过程: 如果一个类加载器收到了类加载的请求, 它首先不会自己去尝试加载这个类, 而是把这个请求委派给父类加载器去完成, 最终所有的加载请求都会传送到顶层的启动类加载器中, 只有当父类加载器反馈自己无法完成这个请求时候, 才由子加载器来加载。

例如类 Object ,它放在 rt.jar 中,无论哪一个类加载器要加载这个类,最终都是委派给启动类加载器进行加载,因此 Object 类在程序的各种类加载器环境中都是同一个类。

对于任何一个类, 都需要由加载它的类加载器和这个类本身一同确定其在 java 虚拟机中的唯一性。

ClassLoader.loadClass() 的代码如下,先检查是否已经被加载过,如果没有则 parent.loadClass() 调用父加载器的 loadClass() 方法,如果父加载器为空则默认使用启动类加载器作为父加载器。如果父类加载器加载失败,抛出 ClassNotFoundException ,再调用自己的 findClass() 方法进行加载。

另外,如果我们自己实现类加载器,一般是 Override 复写  findClass 方法,而不是 loadClass 方法。

protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name); //可以Override该方法}}if (resolve) {resolveClass(c);}return c;}
}

Java 后台的一点知识

JSP 与 Servlet 的关系

  • Tomcat 等 Web 容器最终会把 JSP转化为 Servlet
  • Jsp更擅长表现于页面显示, Servlet更擅长于逻辑控制
  • Servlet是利用  System.out.println() 来输出 html 代码,由于包括大量的HTML标签、大量的静态文本及格式等,导致Servlet的开发效率低下
  • JSP通过在标准的HTML页面中嵌入Java代码,其静态的部分无须Java程序控制,Java 代码只控制那些动态生成的信息
  • 最终 JSP 被容器解释为 Servlet,其中Html 代码也是用 System.out.println() 等拼接输出的
  • JSP 第一次访问的时候,要转化为 java 文件,然后编译为 class 文件,所以第一次访问 JSP 速度会比较慢,后面会快很多

Servlet 生命周期

主要是 java.servlet.Servlet 接口中的 init() 、 service() 、和 destroy() 3个方法。

  • 初始化阶段,web容器通过调用 init() 方法来初始化 Servlet 实例,在Servlet的整个生命周期类, init() 方法只被调用一次
  • 客户请求到来时,容器会开始一个新线程,并调用servlet的  service() 方法, service()  方法根据请求的http方法来调用  doget()  或 dopost()
  • 终止阶段调用 destroy() 方法,销毁一些资源

GET 请求 vs POST 请求

  • GET 用于信息获取,是安全的和幂等的, GET 一般是对后台数据库的信息进行查询
  • POST 表示可能修改变服务器上的资源的请求,一般是对后台数据库进行增、删、改的操作
  • GET 请求的参数会跟在URL后进行传递,请求的数据会附在URL之后,以 ? 分割URL和传输数据,参数之间以 & 相连,一般浏览器对 URL 的长度会有限制
  • POST 请求,提交的数据则放置在是HTTP包的包体中,用类似 Key-Value 的格式发送一些数据,相对来说, GET 请求会把请求的参数暴露在 URL 中,安全性比 POST 差一些

HTTP 请求的基本格式

  • < request line>  请求行
  • <headers>  请求头(参数头)
  • <blank line>  空白行
  • [<request-body>]  请求实体( GET没有, POST有 )

数据库

索引的分类

主要分为聚集索引和非聚集索引:

  • 聚集索引存储记录物理上连续,而非聚集索引是逻辑上的连续,物理存储并不连续
  • 聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个

ResultSet 统计记录数目

Java 中使用 JDBC 连接数据库,最后都会得到一个 ResultSet,比如如下的代码

Connection con = DriverManager.getConnection(url, username, password);Statement sta = con.createStatement();String sql = "select * from student";ResultSet resultSet = sta.executeQuery(sql);

那么如何根据得到的 ResultSet 统计一共有多少条记录呢?注意: ResultSet 没有提供类似 size() 、 length 的 API 来直接获取总记录数。

方法1:利用循环

int sum = 0;
while(resultSet.next()){      sum++;
}

方法2:利用ResultSet的getRow方法来获得ResultSet的总行数

resultSet.last(); //移到最后一行
int rowCount = resultSet.getRow(); //得到当前行号,也就是记录数

设计模式

单例模式

单例模式中必须保证只有一个实例存在。有时候单例是为了避免重复创建多个实例造成资源浪费,有时候也是为了避免多个不同的实例导致系统不一致的行为。

Android 中,App启动时系统会创建一个 Application 对象,用来存储系统的一些信息,这儿的 Application 就是是单例模式的应用。可以通过 Context.getApplicationContext() 获取唯一的 Application 实例。

class Singleton {   private volatile static Singleton instance;   private Singleton() { }   public static Singleton getInstance() {   //第一重判断  if (instance == null) {  //锁定代码块  synchronized (Singleton.class) {  //第二重判断  if (instance == null) {  instance = new Singleton(); //创建单例实例  }  }  }  return instance;   }
}

为什么 synchronized 里面需要加一次判断 if (instance == null) ,是考虑这样的特殊情形:比如线程A、B都到达第一个 if (instance == null) ,线程A进入 synchronized 代码中创建实例,线程B排队等待。但当A执行完毕时,线程B进入 synchronized 锁定代码,它并不知道实例已经创建,将继续创建新的实例,导致产生多个单例对象。

也可以用内部类的方式创建,

public class Singleton(){private static class Inner {private static Singleton instance = new Singleton();}private Singleton() {}public static Singleton getInstance(){return Inner.instance;}
}

模板方法模式

在父类中实现一个算法不变的部分,并将可变的行为留给子类来实现。

比如 AsyncTask 里面的四个方法 onPreExecute 、 doInBackground 、 onProgressUpdate 、 onPostExecute

还有 Activity 也应用了模板方法模式

onCreate 、 onStart 、 onResume 、 onPause 、 onStop 、 onDestroy 、 onRestart

适配器模式

分为两种:类的适配器模式、对象的适配器模式

Android 里的 ListView 和  RecyclerView 的 setAdapter() 方法就是使用了适配器模式。

观察者模式

在 GUI 中,不管是 Windows 桌面应用、或者 Android、IOS,都会给某个按钮 Button 设置监听事件,这儿就是使用了观察者模式。Android 中设置 Button 的监听事件代码如下:

final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {// Perform action on click}
});

笔试编程题

线程 VS 进程

关于线程和进程,不正确的描述是 __ 。(选 D 栈是线程私有, 保存其运行状态和局部变量 )

A. 进程的隔离性要好于线程

B. 线程在资源消耗上通常要比进程轻量

C. 不同进程间不会共享逻辑地址空间

D. 同一个进程的线程之间共享内存,包括堆和栈

E. 进程间有途径共享大量内存中的数据

F. 线程间通讯可以通过直接访问全局变量,或者使用进程间通讯的机制(IPC)

找出未打卡的员工

题目:输入两行数据,第一行为全部员工的 id,第二行为某一天打卡的员工 id,已知只有一个员工没有打卡,求出未打卡员工的 id。(员工 id 不重复,每行输入的 id 未排序)

输入:

1001 1003 1002 1005 1004

1002 1003 1001 1004

输出:

1005

分析:可以用两个 List,第一个 List 保存所有员工的 id,第二个 List 保存打卡员工的 id,从第一个List 中把第二个 List 的数据都删除,最终剩下的就是未打卡员工的 id。

更好的方法:异或,两行数据中未打卡员工的 id 出现了一次,其余员工的 id 都出现了2次,两个相同的数异或为0。

public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String[] ids = scan.nextLine().split(" ");String[] marks = scan.nextLine().split(" ");int result = 0;for (int i = 0; i < ids.length; i++) {result ^= Integer.parseInt(ids[i]);}for (int i = 0; i < marks.length; i++) {result ^= Integer.parseInt(marks[i]);}System.out.println(result);}
}

手写代码题

快速排序

排序是经典面试题,公司也希望通过手写快排来考察面试者的编程习惯和基本功。

// 排序范围 [start, end], 包含 end
public void sort(int[] arr, int start, int end) {if (start < end) {int p = partition(arr, start, end);quickSort(arr, start, p - 1);quickSort(arr, p + 1, end);}
}
// 一次划分代码,返回被划分后的基准位置
public static int partition(int[] arr, int left, int right) {int pivot = arr[left]; while (left < right) {while (left < right && arr[right] >= pivot)right--;if (left < right)arr[left++] = arr[right];while (left < right && arr[left] <= pivot)left++;if (left < right)arr[right--] = arr[left];}arr[left] = pivot;return left;
}

Note:快排是不稳定的,常见的稳定排序是:冒泡、插入、归并

括号字符串是否合法

某个字符串只包括 ( 和 ) ,判断其中的括号是否匹配正确,比如 (()()) 正确, ((())() 错误, 不允许使用栈 。

这种类似题的常见思路是栈,对于左括号入栈,如果遇到右括号,判断此时栈顶是不是左括号,是则将其出栈,不是则该括号序列不合法。

面试官要求不能使用栈,可以使用计数器,利用 int count 字段。

public static boolean checkBrackets(String str) {char[] cs = str.toCharArray();int count = 0;for (int i = 0; i < cs.length; i++) {if (cs[i] == '(')count++;else {count--;if (count < 0) {return false;}}}return count == 0;
}

扑克牌随机发牌

对于52张牌,实现一个随机打算扑克牌顺序的程序。52张牌使用 int 数组模拟。

该算法的难点是如何保证随机性?有个经典算法 shuffle ,思路就是遍历数组,在剩下的元素里再随机取一个元素,然后再在剩下的元素里再随机取一个元素。每次取完元素后,我们就不会让这个元素参与下一次的选取。

To shuffle an array a of n elements (indices 0..n-1):for i from n − 1 downto 1 doj ← random integer with 0 ≤ j ≤ iexchange a[j] and a[i]

注意这儿是 0 ≤ j ≤ i ,包括 j=i 的情况,因为可能洗牌后某个牌未发生交换,比如第51张牌还是原来的第51张牌。

public void randomCards() {int[] data = new int[52];Random random= new Random();for (int i = 0; i < data.length; i++)data[i] = i;for (int i = data.length - 1; i > 0; i--) {int temp = random.nextInt(i+1); //产生 [0,i] 之间的随机数swap(data,i,temp);}
}

智力题

金条付费

你让工人为你工作7天,回报是一根金条,这个金条平分成相连的7段,你必须在每天结束的时候给他们一段金条,如果只允许你两次把金条弄断,你如何给你的工人付费?

答案:切成一段,两段,和四段.

第1天: 给出1.

第2天: 给出2,还回1.

第3天: 给出1.

第4天: 给出4,还回1+2.

第5天: 给出1.

第6天: 给出2,还回1.

第7天: 给出1.

赛马

25匹马,速度都不同,但每匹马的速度都是定值。现在只有5条赛道,无法计时,即每赛一场最多只能知道5匹马的相对快慢。问最少赛几场可以找出25匹马中速度最快的前3名?

答案:

  • 25匹马分成5组,先进行5场比赛
  • 再将刚才5场的冠军进行第6场比赛,得到第一名。按照第6场比赛的名词把前面5场比赛所在的组命名为 A、B、C、D、E 组,即 A 组的冠军是第6场第一名,B 组的冠军是第二名 …
  • 分析第2名和第3名的可能性,如果确定有多于3匹马比某匹马快,那它可以被淘汰了。因为 D 组是第6场的第四名,整个D 组被淘汰了,同意整个 E 组被淘汰。剩下可能是整体的第2、3名的就是C组的第1名、B组的1、2名、A组的第2、3名。取这5匹马进行第7场比赛
    -所以,一共需要7场比赛

2017年高频率的互联网校园招聘面试题相关推荐

  1. 腾讯2017年校园招聘笔试题第一题

    刚做完腾讯2017年校园招聘笔试题,在这里跟大家分享一下: 1. 题目 2. 我的思路 循环判断i(i从2到(输入值/2+1)),是否有满足i和(输入值-i)均为质数的情况.如果有,count加1.循 ...

  2. 腾讯2017年校园招聘笔试题第二题

    下面是腾讯2017年校园招聘笔试题第二题,在这里跟大家一起分享: 1. 题目 2. 我的思路 这题我觉得题目说的很清楚了.用类似于二分查找的方法,记录最大值.最小值和中间值,判断并记录在左区间(值为0 ...

  3. 2005年中兴软件校园招聘笔试题

    2005年中兴软件校园招聘笔试题 第一部分    数据结构和算法 1.      假设执行语句S的时间为O(1),则执行下列程序短的时间为() for(i=1;i<=n;i++) for(j=I ...

  4. 2011-2012年腾讯,创新工场,淘宝,百度,阿里,迅雷。网易游戏校园招聘面试题集锦(1-25题含答案)

    2011-2012年腾讯,创新工场,淘宝,百度,阿里,迅雷.网易游戏校园招聘面试题集锦(1-25题含答案) 又是一年招聘季,小鸟我也在本季参加招聘,所以特在网上和群里面这里去年和今年的面试题,以备战招 ...

  5. 2012九月十月腾讯,网易游戏,百度最新校园招聘笔试题

    十月下旬腾讯,网易游戏,百度最新校园招聘笔试题集锦(第271-330题) 引言 此文十月百度,阿里巴巴,迅雷搜狗最新面试十一题已经整理了最新的面试题70道,本文依次整理腾讯,网易游戏,百度等各大公司最 ...

  6. 赛码浪潮笔试题库软件实施岗位_浪潮集团校园招聘笔试题.doc

    浪潮集团校园招聘笔试题.doc 浪潮集团校园招聘笔试题 浪潮集团校园招聘笔试题篇一:浪潮笔试题目 6.2 笔试题目浪潮软件研发B卷(60分钟) 注:对于有C和JAVA选择的试题,考生可以选择其中一种解 ...

  7. 阿里巴巴集团2014校园招聘笔试题(9月22北京)

    阿里巴巴集团2014校园招聘笔试题 (9月22北京) (答案仅是个人见解,欢迎补充更正,谢谢) 第一部分 单选题(前10题,每题2分:后10题,每题3分.选对得满分,选错倒扣1分,不选得0分) 1.一 ...

  8. 阿里巴巴集团2014校园招聘笔试题------9-22北京 研发工程师

    转自 http://blog.sina.com.cn/s/blog_6f83fdb40101eyzw.html 阿里巴巴集团2014校园招聘笔试题---研发工程师 (9月22北京) (答案仅是个人 ...

  9. 2014 WAP校园招聘笔试题

    2014 WAP校园招聘笔试题 Problem's Link:   http://www.doc88.com/p-6751117015483.html WAP公司笔试题 We are planning ...

最新文章

  1. centos6一键安装vsftpd脚本
  2. 用脚写字考上985!无臂硕士开学报到,宿舍设计太细节了……
  3. java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonProcessingException(Spring使用json的异常处理)
  4. sqlite 日期时间类型学习1
  5. 聊聊springboot2的embeded container的配置改动
  6. csg显示寻找专用服务器失败,支持邻近发现过程的方法和装置
  7. [BUUCTF-pwn]——cmcc_simplerop (ropchain)
  8. [国家集训队] tree Ⅱ
  9. Django运维后台的搭建之四:用bootstrap模板让运维前台变得更漂亮
  10. K8S从懵圈到熟练 - 节点下线姊妹篇
  11. Python zmq 讲解
  12. 每周四JEECG社区公开课:微信公众账号运营(jeewx使用)入门讲解
  13. AcWing1077. 皇宫看守(树形DP)题解
  14. 如何使用Putty登录安装在VirtualBox里的ubuntu 1
  15. request与在php安全,request导致的安全性问题分析
  16. 辉煌十载!BDTC 2017 中国大数据技术大会在京盛大召开
  17. Xcelsius调用CR报表,总是弹出输入参数页面
  18. 在谷歌chrome中打开、编辑、保存金山 WPS Office完美解决方案!
  19. 台湾华夏堂古代玉器收藏家~件件珍贵难得一见
  20. 可以用php做出一个圆锥吗,用H5制作水滴特效教程

热门文章

  1. 报错 插入更新_CentOS中linux网络报错 connect: Network is unreachable问题
  2. r语言读取excel数据_R语言 | 更快的表格文件读取方法!
  3. 收款码合并有什么弊端_为什么明明有个人收款码了,还要申请微信收款商业版?...
  4. One-Error多标签分类_深度学习:如何在多标签分类问题中考虑标签间的相关性?
  5. (5)DFS(深度优先搜索算法):排列数字
  6. oracle检查完系统要求不动,w10安装oracle, 正在检查操作系统要求... 实际结果: 6.2...
  7. python判断数据是否在另一个集合中_python判断一个集合是否包含了另外一个集合中所有项的方法...
  8. android 音频控件,android AudioManager音频控件
  9. Spring mvc 中文乱码
  10. Spring mvc 组件