华为 公共开发部 通用软件工程师
华为一面 基础面试 9.1
第一面比较基础面试,问题也比较少
- 自我介绍
- 说的时候有点没自信,不过面试官一直在找我的笔试数据,好像没怎么注意听。
笔试分析
n个无符号整数,先把每个数的相邻两位进行交换。获得新数,bit0和bit1交换,bit2和bit3交换,例如:101101,那么转换后就是:011110,转换后的n个数进行右移,右溢出的两位作为下一个数的最高两位,最后一个数溢出的两位作为第一个数的最高两位。
有一个x数组和一个y数组,分别代表木板的宽和长,如:[1,2],[3,4],这就代表两块木板,第一块是宽为1长为3,第二块是宽为3长为4。每块木板以宽为底,长为高竖着立起来,木板直接紧密排列,没有间隙,问在这面高低不齐的木板墙上,能张贴面积最大的矩形海报是多大。
- 第一题用了一个半小时,我自己的设计的测试用例都过了,然后跑起来通过用例百分之零
- 原因:首先整体思路经后期检验,是没有问题的,最大的问题在于数据类型的装换。
要求是无符号整数(unsigned int),但是java中没有这种整数类型,只能用有符号的整型进行运算(因为都是32位,直接看成无符号整数就行)。 - 我的错误做法: 我做题的时候认为既然整数部分没有办法满足,那我就用以个long进行接收。结果就全错了。
个人认为这种题目应该多给点例子,这道题我做完隔天立刻做到这种位相关题目,题目明确要求让我用整型去代替无符号整数而不是用long,我看到就很明确了,而我个人觉得,确实会有这种歧义出现。
- 原因:首先整体思路经后期检验,是没有问题的,最大的问题在于数据类型的装换。
- 第二题只剩下半个小时,而且也是十分紧张,因为时间剩下非常少,而我目前是0分状态。
- 所以我想都没想直接暴力解法,但是其实我在做的过程中就知道可能可以使用二分或者动态规划进行优化,但是没时间细想,做完只剩下几分钟。
- 知道的数据结构
一开始回答成数据类型,这点一定要区分-_-
- 数组:数组是可以在内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始。
- 栈:栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出。
- 队列:队列与栈一样,也是一种线性表,不同的是,队列可以在一端添加元素,在另一端取出元素,也就是:先进先出。
- 链表:链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。
- 树:树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。
- 散列表:散列表,也叫哈希表,是根据关键码和值 (key和value) 直接进行访问的数据结构,通过key和value来映射到集合中的一个位置,这样就可以很快找到集合中的对应元素。
- 堆:堆是一种比较特殊的数据结构,可以被看做一棵树的数组对象,具有以下的性质:
- 堆中某个节点的值总是不大于或不小于其父节点的值;
- 堆总是一棵完全二叉树。
- 图:图是由结点的有穷集合V和边的集合E组成。
- list,set,map的数据存储区别
- list和set继承自Collection接口,是一个个数据存进去的。
- list里面的元素是有序的,按插入顺序排列的,且是可重复的。
- set里面的元素是无序的,一般都是使用对应的map实现功能,将数据存在key上保证唯一性。
- map继承自Map接口,map里面有一个entry,对应键值对,键值key映射着对应的值,key是唯一的,但是value不是。
- 开发上遇到的困难
这一点我认为我答的不够好,不够精简,但是这道题我认为实在是太泛了,如果具体到某个项目会好一点
这里我主要提到版本问题:
- Spring Security的密码前需要加上加密编码类型标识(5.x之后)。
- Spring Cloud在分布式配置中,使用github的webhook功能实现实时更新,在Config服务器中,新版本需要配置serviceId,此id分为三部分,服务名:激活区名:instanceId(没有可以加上一个随机数)。
- ........(此题具有个人差异性,其他自行脑补)
- 你知道的加密算法
我并不知道有哪些具体的加密算法,但是我讲了什么是对称和非对称加密
- 对称加密:对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密用的是同样的密钥。(对称加密通常使用的是相对较小的密钥)
- 非对称加密:非对称加密使用了一对密钥,分别是公钥和私钥。公钥用于发给需要使用到的一方,对方使用公钥对数据进行加密,而私钥只能保管在一方那里,用于解密使用对应公钥加密的数据。(非对称加密一般比较复杂,用时也比较长)
- 一般当前最常用的就是两种方式结合,用非对称加密去加密对称加密的密钥,这样既安全,但是又不会耗时太长,因为堆成加密的密钥一般不会太长的。(这一点要是有时间可以谈谈https的加密方式)
- 对称加密的算法:DES、3DES、AES、DESX、Blowfish、、RC4、RC5、RC6。
- 非对称加密的算法:RSA、DSA(数字签名用)、ECC(移动设备用)、Diffie-Hellman、El Gamal。
- 多线程的实现方式
- Thread:
- Thread类是在java.lang包中定义的。
- 一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了
- 一个类只能继承一个父类,这是此方法的局限。
- Runnable
- 使用Runnable定义的子类中没有start()方法,只有Thread类中才有。
- Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。
- 优势:
- 避免点继承的局限,一个类可以继承多个接口。
- 适合于资源的共享
- Callable
- Callable 和 Runnable 的使用方法大同小异, 区别在于:
- Callable 使用 call() 方法, Runnable 使用 run() 方法
- call() 可以返回值, 而 run()方法不能返回。
- call() 可以抛出受检查的异常,比如ClassNotFoundException, 而run()不能抛出受检查的异常。
- Callable 和 Runnable 的使用方法大同小异, 区别在于:
- 知道多少种排序
在AuditionPoints文件夹中有一个code文件夹,里面有我写的八大排序算法的java实现
- 冒泡排序
- 选择排序
- 插入排序
- 希尔排序
- 快速排序
- 归并排序
- 基数排序
- 堆排序
- (拓扑排序)
- 说说快速排序
该方法的基本思想是:
- 1.先从数列中取出一个数作为基准数。
- 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 3.再对左右区间重复第二步,直到各区间只有一个数。
- 写一道算法题
20 - 25分钟,第一次面试比较紧张,最后没有跑过,但是后来写出了答案,也学习到了排序map的一种方式
这里谢谢面试官提醒(又再一次被面试官说java基础不够熟悉)
/** * 题目:投票计数器 * 内容:给定一组名字字符串,名字和名字之间逗号隔开, * 按照票数高低的顺序输出票名字空格数,相同票数的按照字母升序输出 * 输入例如:xiaoming,xiaozhang,xiaoli,zhangsan,xiaoming * 输出:xiaoming 2,xiaoli 1, xiaozhang 1,zhangsan 1 */ public class Huawei1 { public static void main(String[] args) { Scanner in = new Scanner(System.in); String input = in.nextLine(); String[] names = input.split(","); HashMap<String, Integer> map = new HashMap<>(); for (String name: names){ int vote = map.getOrDefault(name, 0); map.put(name, vote + 1); } List<Map.Entry<String , Integer>> list = new ArrayList<>(); list.addAll(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { int res = o2.getValue() - o1.getValue(); if (res == 0){ res = o1.getKey().compareTo(o2.getKey()); } return res; } }); for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i).getKey() + " " + list.get(i).getValue()); if (i != list.size() - 1){ System.out.print(","); } } } }
对于面试,面试官觉得我对于Java数据结构的编程使用上还不够熟练
反思过之后,确实局限于我学习Java的时间不长,很多不太熟练,所以我进行了一个API的总体练习回顾
#面经##华为##Java工程师##校招#