阿里2017校园招聘电话面试总结

话说昨晚九点,博主兴高采烈的准备去超市购物,一不小心手机来了通电话,根据提示是阿里巴巴,晕菜,肯定是跟20天前提交的内推职位有关。怕不接就再没机会了,于是豁出去了,接!

果然,一个很有磁性的面试官开始说了几句话,然后就让做自我介绍了,我连自我介绍都紧张的不行,大脑空白啊!这是智商不够的体现啊!我就说想寻求java研发工程师的工作。。。。。。

然后下面是一些面试中出现的**状况。

题目一 首先就是SSH框架中的Spring,主要是IoC,让我讲一下是怎么个原理。我已经想不起来了,小伙伴们好好复习一下,再做几个例子感受感受可能就说上来了。

Spring工作原理 
        Spring内部最核心的就是IOC了, 动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射 反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml  Spring的配置 文件来动态的创建对象,和调用对象里的方法的 。 
     Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过 配置类达到的。 
   Spring目的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明 
管理的(Spring根据这些配置 内部通过反射去动态的组装对象) 
 要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。 Spring里用的最经典的一个设计模式就是:模板方法模。

一、IoC(Inversion of control): 控制反转 

1、IoC: 
概念:控制权由对象本身转向容器;由容器根据配置文件去创建实例并创建各个实例之间的依赖关系 
核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean 
二、AOP(Aspect-Oriented Programming): 面向方面编程 
1、 代理的两种方式: 
静态代理:   针对每个具体类分别编写代理类;   针对一个接口编写一个代理类; 
动态代理: 针对一个方面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类 。
2、 AOP的主要原理:动态代理 
题目
:数据结构中二叉树中如何删除一个节点?

二叉树删除节点分多种情况讨论:

  1. 被删除节点没有子树的情况,直接删除,并修改对应父节点的指针为空。

  2. 对于只有一个子树的情况,考虑将其子树作为其父节点的子树,关于是左还是右,根据被删除的节点确定。

  3. 最复杂的是有两个子树的情况,可以考虑两种方法,都是同样的思想:用被删除节点A的左子树的最右节点或者A的右子树的最左节点作为替代A的节点,并修改相应的最左或最右节点的父节点的指针,修改方法类似2 。

/**********删除二叉树节点的操作***********/
btree deletenode(btree root,int node)
{
 btree parent;
 btree point;
 btree child;
    int postion;

 parent=binary_search(root,node,&postion); 
 //二叉树为空的情况
   if(parent==NULL)
  return root;
   else
   {
    switch(postion)
   { case -1:point=parent->left;break;
  case 1 :point=parent->right;break;
  case  0 :point=parent;break;
   }
 if(point->left==NULL&&point->right==NULL)
 {
  switch(postion)
  {
         case -1:parent->left=NULL;break;
         case 1:parent->right=NULL;break;
         case 0:parent=NULL;break;
  }
    free(point);
   return root;
    }
 if(point->left==NULL&&point->right!=NULL)
  {
   if(postion==-1)
    parent->left=point->right;
   else
    if(postion==1)
    parent->right=point->right;
    else
     root=root->right;
   free(point);
   return root;
  }
  
 if(point->left!=NULL&&point->right==NULL)
 {
  if(postion==-1)
   parent->left=point->left;
  else
   if(postion==1)
    parent->right=point->left;
   else
    root=root->left;
  return root;
 }
 if(point->left!=NULL&& point->right!=NULL)
 {
  parent=point;
  child=point->left;
  while(child->right!=NULL)
  {
   parent=child;
   child=child->right;
  }
  point->data=child->data;
  if(parent->left=child)
   parent->left=child->left;
  else
   parent->right=child->left;
  free(child);
  return root;
    }
  }
}

或者

Tree *Delete(Tree *T,int n)
{
    //将树中指定节点删除的函数
    Tree *tmp;
    if(T==NULL)
        return NULL;
    if(T->element==n)
    {
        if(T->right==NULL)                       //如果没有右子树,即只有一个该节点儿子左子树
        {                                        //则直接删除
            tmp=T;
            T=T->left;                            //用左子树节点代替父节点
            free(tmp);
        }
        else                                     //如果右子树存在
        {
            tmp=T->right;
            while(tmp->left!=NULL)
                tmp=tmp->left;                   //找到右子树的值最小的节点
            T->element=tmp->element;             //用该节点的值代替原来的节点的值
            T->right=Delete(T->right,tmp->element);                         //递归的删除右子树中用来代替源节点值的节点
            T->height = MAX(Height(T->left),Height(T->right)) + 1;
        }
        return T;
    }
    if(n < T->element)
        T->left = Delete(T->left,n);
    else
        T->right = Delete(T->right,n);
    T->height = MAX(Height(T->left),Height(T->right)) + 1;
    return T;
}


下面以实例来解释,假设要删除下图的节点2,


如图,要删除节点2,先看节点2有没有右子树;有右子树,找到其右子树中值最小的节点,于是找到了3;把3的值赋给节点2,现在变成第2附图;下面要递归的删除其右子树中的3节点。

5比3大,所以left递归找到3;3有右子树4,所以要找到3的右子树的值最小的节点。4是其唯一的值,肯定是其最小的节点。于是把4赋给3,变成第3幅图;下面要删除4的右子树中给其赋值的节点4.第一个就是4,好巧,看看其有没有右子树,没有,光杆司令一个;直接删除该节点,把NULL赋给4;于是变成第4幅图。


题目三链表中如何倒序:由a->b->c->d,变为d->c->b->a,并且不占用内存空间。

我给出的是这种思想,定义两个数组,引入一个变量,但是好像占用了很多空间,面试官并不是很happy。。。

#include <stdio.h>
void main()
{
int n,i,j,t;
int a[1000];
scanf("%d",&n); //输入输入正整数的个数
for(i=0;i<n;i++)
scanf("%d",&a[i]); //输入n个正整数
for(i=0,j=n-1;i<j;i++,j--)
{
t=a[i];
a[i]=a[j];
a[j]=t;
} //进行倒序排列
for(i=0;i<n;i++)
printf("%d\t",a[i]); //输出排列后的数列
}
再从网上搜索点类似的,,,
//逆序 
void reverseNodeList() 
{ 
if(NULL == head) 
{ 
return; 
} 
//如果链表长度为1 
if(head->pNext == NULL) 
{ 
return; 
} 
Node* p = head->pNext; 
Node* q = p->pNext; 
Node* t = NULL; 
while(NULL != q) 
{ 
t = q->pNext; 
q->pNext = p; 
p = q; 
q = t; 
} 
head->pNext->pNext = NULL; 
head->pNext = p; 
} 
还有就是询问了一下自己的英文水平,由于读写还行,听说不好,所以就只能实话实说了,我怕自己说大话,面试官直接跟我讲英文。。。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值