1.首先依然是惯例的自我介绍,然后开始聊了一下项目,这次就问了一下自己的产品模块是怎么实现的,怎么设计的数据库表,怎么理的逻辑结构
2.讲一下Spring 的IOC是什么意思
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建
传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象
有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
3.我这里有一些自己的依赖包需要加到项目中,我需要怎么进行配置
4.看你用到了Hibernate,那你对其他的ORM框架有了解吗,MyBatis与Hibernate的区别有什么
1. hibernate是全自动,而mybatis是半自动
hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。
2. hibernate数据库移植性远大于mybatis
3. hibernate拥有完整的日志系统,mybatis则欠缺一些
4. mybatis相比hibernate需要关心很多细节
5. sql直接优化上,mybatis要比hibernate方便很多
5.给我讲一讲hashmap
首先讲一下hashmap是一个怎样的数据结构,然后如何散列,如果遇到冲突采用链地址法,如果链超过长度则转为红黑树(JDK1.8),具体请看链接。
HashMap实现原理及源码分析
6.算法题1:实现一下链表反转(我用了头插法,他又让我写了一下不用头插只用三个辅助空间的方法)
算法思路:每次new一个新的节点和当前节点相同,插在链表的头部,将链表往下继续找;
头插法:
public static Node reverse(Node head)
{
if(null == head || null == head.nextNode)
{
return head;
}
Node tempHead = new Node(); //新链的头节点
while(head.nextNode != null)
{
Node next = head.nextNode;
head.nextNode = tempHead.nextNode;
tempHead.nextNode = head;
head = next;
}
return tempHead.nextNode;
}
算法思路:一个变量保存当前节点指向的下一个链表,保证链表不断开,然后当前节点的next反转指向前面
反转next法:
public Node reverse(Node head) {
if(null == head || null == head.nextNode)
{
return head;
}
Node prev = null;
Node now = node;
Node next = null;
while (now != null) {
next = now.next;
now.next = prev;
prev = now;
now = next;
}
return prev;
}
7.算法题2:一颗二叉搜索树,给定一个值target,如何确定二叉搜索树里面最接近的值
LeetCode 270
算法思路:target 一定在找的path 上,若是出现了比minDiff 还小的 差值,就把改点更新为cloest.但注意target 是 double, 会有溢出情况,所以minDiff 初始化成Double.MAX_VALUE.
Time Complexity: O(h). h 是树的高度. Space: O(1).
public int closestValue(TreeNode root, double target) {
if(root == null){
return -1;
}
int cloest = root.val;
double minDiff = Double.MAX_VALUE;
while(root != null){
if(Math.abs(root.val - target) < minDiff){
minDiff = Math.abs(root.val - target);
cloest = root.val;
}
if(target > root.val){
root = root.right;
}else if(target < root.val){
root = root.left;
}else{
return root.val;
}
}
return cloest;
}
8.算法题3:写一个数组的二分查找,如果我有十亿个数,如何找到最大的十个
构造一个10个元素的最大堆,进行10亿次调整即可
public static int biSearch(int []array,int a){
int lo=0;
int hi=array.length-1;
int mid;
while(lo<=hi){
mid=(lo+hi)/2;
if(array[mid]==a){
return mid+1;
}else if(array[mid]<a){
lo=mid+1;
}else{
hi=mid-1;
}
return -1;
}
8.算法题4:青蛙一次可以跳一个台阶或两个台阶,跳上n级台阶有多少种情况
剑指offer常见斐波那契的题
public int Fibonacci(int n) {
if(n == 1 || n == 2) return n;
int Fpre = 1, Fnow=1, Fnext = 0;
for (int i = 3; i <= n; i++) {
Fnext = Fpre +Fnow;
Fpre = Fnow;
Fnow = Fnext ;
}
}
}
9.算法题5:层次遍历是怎么实现的,口述一下非递归方法
用队列
void LevelOrder(BiTree T){
Queue Q;
Q.add(T); //加入根节点
while(!Empty(Q)){
Y =Q.remove(); // 移除队列头
System.out.println(Y.data);//访问
if(Y.leftchild!=null){
Q.add(Y.leftchild);//左右树不空,放入左右子树根节点,循环
}
if(Y.rightchild!=null){
Q.add(Y.rightchild);
}
}
}
10.算法题6:一个排序数组,找哪两个和为target
leetcode一道题,双指针类型的
Pairs SumToK(int *arr,int len,int k)//时间复杂度O(n),空间复制度O(1)
{
Pairs pa = {-1,-1};
int low = 0; //从前往后遍历
int high = len-1;//从后往前遍历
int sum;
while(low <= high)
{
sum = arr[low] + arr[high];
if(sum < k)
{
low++;
}
else if(sum > k)
{
high--;
}
else
{
pa.x = low;
pa.y = high;
break;
}
}
return pa;
}
10.怎么求圆周率
π
4
=
1
−
1
3
+
1
5
−
1
7
+
1
9
.
.
.
\frac{\pi}{4}=1-\frac{1}{3}+\frac{1}{5}-\frac{1}{7}+\frac{1}{9}...
4π=1−31+51−71+91...
知道公式就行了,然而我真不知道…