2018/9/19 14:45:51
技术面两个人,会问许多基础的问题,对项目也会问很多,基本把计算机基础知识都问一遍,语言、数据结构、数据库、操作系统、计算机网络等等,总的来说,基础要扎实。
1. 怎么使用单例模式?面试官(不是创建,是使用。。。,)new不行
2. final关键字。。。
3.hashmap♥
4.红黑树♥
5.LRU(解决本题的方法是:双向链表+HashMap)
6.数据库插入语句
7.宏语句
8.数据库引擎
9.生产者消费者原理♥
10.tomcat服务器?如何保持session的一致性?死锁问题。
11.C 虚函数表是什么? 实现优先级队列?为什么不用排序数组而用堆? 写个二分查找?
12.平衡二叉树
深度优先遍历
1.数据结构:循环队列长度计算,双向链表插入,hash表数组存储结构平均访问长度,完全二叉树,满二叉树,小顶堆,给出后序中序遍历求前序遍历,归并排序时间复杂度,哈夫曼编码。
2.计算机网络:网络延迟定义,cookies。
3.操作系统:缓存区作用,内存动态分配(最佳适应算法,首次适应算法,最坏适应算法),临界区。
4.编程:判断一个N维矩阵是否为对称矩阵;两个数组(A和B)进行两两相加,结果存在C中,求C中第k小的数;判断朋友圈个数(深度优先遍历实现)。
4.http协议工作原理是什么?通信过程中经常涉及到http协议,它的过程是什么?
首先介绍了它是超文本传输协议,基于TCP实现的,通常是客户端发送请求。我之前接触过get()和post()方法,结合做的通信的开通彩铃业务,怎么去实现的,介绍了get和post的区别。
5.生产者消费者模式 怎么去实现,画一下流程。需要一个共享存储区域,一般是队列,然后生产者放,消费者取,多个消费者的话涉及到多线程,要保证数据一致性,需要上锁或者设置互斥变量。
作者:德普男神的花裤衩儿
链接:https://www.nowcoder.com/discuss/48125
来源:牛客网
我选了C++,手写了个冒泡,然后不用第三个变量交换,然后引用和指针的区别,const关键字的作用,mapreduce的基本流程(这个主要我简历上写了),c和c++内存分配的区别。二面问为什么不读研,聊了下四六级分数,然后校园活动,期望工作地点,是否接受调剂,对电信的了解,期望薪资。
【回答部分】
-----------------------------------------------------------
【操作系统】
死锁(什么是死锁+如何避免死锁)
产生死锁的原因主要是:
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。 如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则 就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
产生死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之 一不满足,就不会发生死锁。
死锁的解除与预防: 理解了死锁的原因,产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确 定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。
处理死锁的方法有四种:1) 预防死锁 2) 避免死锁 3)检测和解除死锁
预防死锁:破坏四个必要条件之一即可
①破坏互斥条件:让资源允许共享,如SPOOLing技术就可以允许若干个进程同时产生打印数据,
缺点: SPOOLing的技术并不适用于所有的资源,如进程表等,所以破坏资源的互斥性是比较困难的,该方法并不是很好
②破坏请求和保持条件:资源一次性分配。
缺点:采取这种机制,那么进程在执行过程中就不再申请资源了,但这种方法的效率极低,资源无法得到充分的利用。
③破坏不可剥夺条件:有两种方法,一种是当其申请的资源得不到满足时,也必须放弃其原先占有的资源;另一种方法是只适用于申请资源的进程优先级比占有该资源的进程优先级高时,如果一个进程申请的资源被其它进程占用,而申请进程的优先级较高,那么它可以强迫占有资源的进程放弃。这种方法一般适用于处理机和存储资源。
④破坏循环等待条件:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(如:哲学家进餐问题)
避免死锁的方法有两种:1) 资源按序分配 2) 银行家算法。
解除死锁的方法有两种:1) 资源剥夺法 2) 撤消进程法 3)进程回退法
注意:
讲一讲死锁问题?答题内容:什么是死锁+如何避免死锁。
讲一讲如何避免死锁?答题内容:死锁发生的原因+解决方法。
生产者消费者
PV原语
linux命令(cat,rm,mkdir,top,ps,du,contab)
contab:通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。
LRU
死锁产生的条件:
互斥请求
不可剥夺
循环等待
请求保持
进程和线程的区别:
进程是资源拥有的基本单位,线程是CPU调度和分派的基本单位。
一个程序至少有一个进程,一个进程至少有一个线程。
进程在执行程序中拥有独立的内存单元,而多个线程共享内存,从而极大地提高程序的运行效率。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
-----------------------------------------------------------
【数据结构和算法】
各种排序(冒泡排序、折半排序、快排、归并排序、堆排序)
链表
二叉树、
平衡二叉树、
栈
红黑树
优先队列
优先队列的主要操作:入队、出队(取出优先级最高的元素)
实现:三种实现(普通数组、顺序数组、堆)
通常情况下,我们使用堆可以平衡入队和出队。
对于总共N个请求:
使用普通数组或者顺序数组,最差情况:O(n^2)
使用堆稳定在:O(nlgn)
-----------------------------------------------------------
【计算机网络】
TCP/IP三次握手
四次挥手
http协议
应用层协议有哪些
OSI七层参考模型
-----------------------------------------------------------
【数据库】sql
插入,有两种情况,插入完整的一条语句;第二种是往某些列中插入数据。
(1)insert into 表名 values (值1,值2,.....)
(2)insert into 表名 (列1,列2,....) values (值1,值2,...)
一个学生表,一个成绩表,求每个学生的总分数。
SQL:left join+sum(cored)函数+group by(学生id)
http://www.runoob.com/sql/sql-groupby.html
数据库引擎:
http://hcxblog.com/2016/11/07/Interview-summary/
在MySQL 5.5之前,MyISAM是mysql的默认数据库引擎,但是不支持事务处理。所以现在使用的是InnoDB数据引擎。Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
数据库中的事务的四个特点:一格子酒。
一致性、隔离性、原子性、持久性。
⑴ 原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
⑵ 一致性(Consistency)(备注:有种守恒的感觉,就是不管状态怎么变化,执行之前和执行之后是处于一致性的状态当中)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
⑶ 隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
关于事务的隔离性数据库提供了多种隔离级别。
数据库管理系统采用锁机制来实现事务的隔离性。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
⑷ 持久性(Durability)-(备注:一旦保存,不能再撤回)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
-----------------------------------------------------------
【C++面试】
虚函数、虚函数表、指针和引用、多线程、STL和STL源码、进程和线程、并发和同步、final
final:在类的名称后面写上final,表示这类不能继续派生出新的类。如果在函数的参数列表后面加上final,表示在子类当中,不能继续重写这个函数。
static特点以及和全局变量的区别:
static的特点:首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。
1.static和全局变量的区别:
(1)static变量只能在声明的文件中使用,不能在其他的文件中使用,但是全局变量可以整个源程序中使用。(2)static变量只能初始化一次。
2. static局部变量和普通局部变量有什么区别 ?
(1)生命周期不同,static变量在整个程序的运行周期都有效,但是局部变量在推出作用域之后,就失效了。
(2)初始化不同:static变量只初始化一次,下一次的值是在上一次值得基础上进行变化。
3. static函数与普通函数有什么区别?(只有隐藏的作用)
(1)作用域不同:static函数的只在所在文件中有效。普通的函数如果想要被其他文件引用,只要在使用这些函数的源文件中包含一个声明了普通函数的头文件就可以。
(2)份数不同:在内存中只有一份static函数,但是普通函数可以有很多份。只要普通函数被调用一次就需要维持一个拷贝。
(3)位置不同:static函数是静态函数。
static作用:
修饰局部变量:
1.延长局部变量的生命周期,程序结束才会销毁。
2.局部变量只会生成一份内存,只会初始化一次。
3.改变局部变量的作用域。
修饰全局变量
1.只能在本文件中访问,修改全局变量的作用域,生命周期不会改
2.避免重复定义全局变量
=>关键点:作用域、生命周期、初始化次数、隐藏、共享
由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
static全局变量只初使化一次,防止在其他文件单元中被引用;
指针和引用:
指针:就是一个变量的地址 引用:就是一个变量的别名
区别:
1. 空值:指针可以为空;引用不能是空,在声明的时候必须赋值。
2. 改变:指针的值可以更改;引用赋值之后不能在改变。
3. 大小:指针大小为4字节(32位系统);引用仅为别名,大小为其依附数据对象的大小。
4. 安全:指针没有类型检查;引用有类型检查。
5. 访问:指针间接访问对象;引用直接访问对象。
小结:在函数参数传递中,指针与引用均可解决大块数据或对象传递效率低和空间开销大的问题。
【设计模式】
消息队列
https://blog.csdn.net/hxpjava1/article/details/81234929
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。
目前在生产环境,使用较多的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ等。
作者:步积
链接:https://www.jianshu.com/p/689ce4205021
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
单例模式实现
https://blog.csdn.net/liang19890820/article/details/61615495
回答套路:什么是单例模式+写代码+简单讲一下代码(主要是说代码中必须要有什么)+强调单例模式使用的重点。
(1)什么是单例模式:单例模式(Singleton Pattern)是设计模式中最简单的形式之一,其目的是使得类的一个对象成为系统中的唯一实例。
(2)单例模式的使用(具体的C++代码)比如懒汉式的单例模式:
// singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
// 单例 - 懒汉式/饿汉式公用
class Singleton
{
public:
static Singleton* GetInstance();
private:
Singleton() {} // 构造函数(被保护)
private:
static Singleton *m_pSingleton; // 指向单例对象的指针
};
#endif // SINGLETON_H
(3)分析代码:
从具体实现角度来说,可分为以下三点:
- 提供一个 private 构造函数(防止外部调用而构造类的实例)
- 提供一个该类的 static private 对象
- 提供一个 static public 函数,用于创建或获取其本身的静态私有对象(例如:GetInstance())
(4)强调(单例模型)其中的规律。
单例模式的要点有三个:
- 单例类有且仅有一个实例
- 单例类必须自行创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
这些说完就已经很完整了。