杭州某公司
笔试题照片
笔试解答
计算机基础题(必做)
1.略
2.内存溢出和内存泄露
内存溢出是指已有的数据超过了其获得到的内存所能存储的范围,比如用一个字节存放1000这个数字就属于内存溢出;
内存泄漏是指程序由于错误或漏洞造成的内存占用过多,或占用内存后无法释放(很多情况是申请了内存,但程序结束后没有释放)。
3.数据库中索引,主键,唯一索引,联合索引的区别,对数据库性能有什么影响
- 索引是一种特殊文件,它包含对数据表里所有记录的引用指针
- 普通索引的唯一作用是加快访问速度
- 普通索引,被索引的数据中可以包含重复的数据,唯一索引就是规定了索引到的值各不相同
- 主键是一种特殊的唯一索引,一个表中只能允许有一个主键,用来唯一标识一条记录
- 联动索引就是索引可以覆盖多个数据列
- 索引加快了查询的速度,但是减慢了添加删除更新的速度,因为在执行这些操作之前需要先索引
4.数据库中内联接和外联接区别
- 内连接:指连接结果仅包含符合连接条件的行,参与连接的两个表都应该符合连接条件。
- 外连接:连接结果不仅包含符合连接条件的行同时也包含自身不符合条件的行。包括左外连接、右外连接和全外连接。
内连接只能查询两个表中关系匹配的记录外连接不仅能查询两个表中关系匹配的记录,而且可以查询不匹配的纪录
5.线程和进程,多线程中死锁怎么处理
联系:
- 一个线程只属于一个进程,一个进程可以拥有多个线程,但至少有一个线程,称为主线程
- 资源统一分配给进程,同一进程中的线程共享该进程的所有资源
- 线程在执行过程中,需要协作同步,不同进程之间线程需要通过消息通信来达到同步
区别:
- 线程作为调度和分配的基本单位,进程作为分配资源的基本单位
- 并发性:不仅进程之间可以并发执行,同一进程中的不同线程之间也能进行并发执行
- 拥有资源:进程是拥有资源的独立单位,线程不拥有资源,但可以访问隶属于进程的所有资源
什么时候用多线程:
- 耗时或大量占用处理器阻塞用户界面操作
- 各个任务必须等待外部资源时
避免多线程中死锁
- 加锁顺序(线程按照一定的顺序加锁)
- 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
- 死锁检测
6.缓存的应用场景
- 我们先解释下缓存, 顾名思义,就是数据暂存的地方,你可以理解为从磁盘里取出来数据,暂时存放在内存,以待后面处理来读取。而能存放在缓存的数据,通常是频繁访问的,不会经常修改的数据。知道了什么是缓存,什么数据可以放缓存,就可以寻找合适的缓存(这里说的缓存,就是对象或者容器了)。
- 目前,缓存的操作主要是两种方式,一种是使用程序自带的map对象(像jdk的hashmap),一种是缓存软件,第一种不细说,大家可以看看hashmap的实现和应用,这里主要说缓存软件。现在流行的缓存软件是memcached、redis(如果有不了解的,google),有的博客还说到mongodb。个人认为,因为要兼顾DB的某些特性,所以做不到其他两个缓存的为了实现极高的吞吐量而采用的epoll 或 libevent事件驱动的方案,所以这里排除。下面所说的缓存,就指的是第二种。
7.略
8.略
9.TCP和UDP区别
- 基于连接与不连接
- UDP程序结构简单
- 对系统资源的要求,TCP多,UDP少
- TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
- 流模式,数据报模式
10.观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
前端笔试题
1.css有哪些选择器,如何区分优先级,下面的代码是什么效果
- 派生选择器(用HTML标签申明)
- id选择器(用DOM的ID申明)
- 类选择器(用一个样式类名申明)
除了前3种基本选择器,还有一些扩展选择器,包括
- 后代选择器(利用空格间隔,比如div .a{ })
- 群组选择器(利用逗号间隔,比如p,div,#a{ })
CSS选择器的优先级的定义
基本原则:
一般而言,选择器越特殊,它的优先级越高。也就是选择器指向的越准确,它的优先级就越高。
复杂的计算方法:
- 用1表示派生选择器的优先级
- 用10表示类选择器的优先级
- 用100标示ID选择器的优先级
- div.test1 .span var 优先级 1+10 +10 +1
- span#xxx .songs li 优先级1+100 + 10 + 1
- #xxx li 优先级 100 +1
<style>
#id{color:green;}
.class-a{
color:blue;
}
#my-id.class-b{color:yellow;}
p.class-a.class-b{
color:red;
}
</style>
<body>
<p class="class-b class-a" id="my-id">123</p>
</body>
答案是yellow,黄色
2.如何用css让一个元素不可见
- opcity: 0; 隐藏对应的元素并且挤占该元素原来的空间。
- display : none; 隐藏对应的元素但不挤占该元素原来的空间。
- visibility: hidden; 隐藏对应的元素并且挤占该元素原来的空间。
即是,使用CSS display:none属性后,HTML元素(对象)的宽度、高度等各种属性值都将“丢失”;而使用visibility:hidden属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在。
3.补充一下.b的css代码,使得<div class="b"></div>在页面水平居中,列出你能想到的所有方法
.b{
width:200px;
height:100px;
background:#ccc;
//继续补充代码
}
传统的居中方式
添加代码margin:0 auto;即可
绝对定位方式(必须已知子元素宽高,并且父元素需要relative定位)
添加代码
position:absolute;
left:50%;
margin-left:-100px;
绝对定位方式(不用知道子元素宽高,但父元素需要relative定位)
position:absolute;
left:0;
right:0;
margin:0 auto;
4.如果一个页面因为图片大且多加载慢,应该如何去优化?
- 图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
- 如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
- 如果图片为css图片,可以使用CSSsprite,SVGsprite,Iconfont、Base64等技术。
- 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
- 如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致。
5.如何消除一个数组里面重复的元素?
这个是一个常考题,网上一搜方式很多。
首先介绍一种es6的解决方法
ES6里新添加了两个很好用的东西,set和Array.from。
set是一种新的数据结构,它可以接收一个数组或者是类数组对象,自动去重其中的重复项目。
var arr = [1,1,'1','1',null,null,undefined,undefined,NaN,NaN];
console.log(new Set(arr));
在这我们可以看见,重复的项目已经被去掉了,包括NaN。正常情况下,NaN === NaN 返回的是false,但是在set里,一样能够帮你去重。
但是这里大家可以看到,set返回的是一个对象,但是我们想要的是数组啊。
这回,就该轮到Array.from出场了,它的作用,就是可以把类数组对象、可迭代对象转化为数组。
var arr = [1,1,'1','1',null,null,undefined,undefined,NaN,NaN];
var newArr = Array.from(new Set(arr));
console.log(newArr);
再介绍一种利用indexOf方法的去重
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
var arr = [1,1,2,3,4,2,6,4,5,7];
var nArr = [];
function removeItem(arr){
for(var i=0;i<arr.length;i++){
if(nArr.indexOf(arr[i])==-1){
nArr.push(arr[i]);
}
}
return nArr;
}
console.log(removeItem(arr));
6.请简述var let const的区别
- var定义的变量可以修改,如果不初始化会输出undefind,并且有时候会泄露到全局,造成一些影响
- 为了解决这个泄露的bug,有了es6的let,let相当于给行数定义了一个块级域,函数内部使用let定义的变量只能在函数内部起作用
- const是用来定义一个不变的量,不能修改的量,必须赋初值
7.如何深拷贝对象,JSON.stringfiy需要注意什么
讲讲浅拷贝和深拷贝的概念,js中的浅拷贝和深拷贝,知识针对复杂数据类型(Object,Array)的复制问题。
- 浅拷贝:是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响
var a = {c:1};
var b = a;
console.log(a === b); // 输出true。
a.c = 2;
console.log(b.c); // 输出 2
- 深拷贝:在堆中重新分配内存,并且把资源对象所有属性都进行新建拷贝,拷贝后的对象与原来的对象是完全隔离,互不影响
常见方法有JSON.parse(),JSON.stringify(),jQury的$.extend(true,{},obj)
var a = {c: {d: 1}};
var b = $.extend(true, {}, a);
console.log(a === b); // 输出false
a.c.d = 3;
console.log(b.c.d); // 输出 1,没有改变。
- JSON.stringfiy需要注意什么
首先讲一下JSON.parse()和JSON.stringfiy的概念
JSON.parse()是将字符串转黄成json对象
var str = '{"name":"zp","age":"22"}'
结果:
JSON.parse(str)
Object
age: "22"
name: "zp"
__proto__: Object
JSON.stringfiy则相反,是将json对象转换成字符串
vara = {a:1,b:2}
结果:
JSON.stringify(a)
"{"a":1,"b":2}"
JSON.stringfiy需要注意的地方
JSON.stringfiy将不会转换不具有json表示形式的值
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null
undefined不在其中。
8.<a onclick="a.click">和<a onclick="a.click()">两者的写法有差别吗,如果有,差别是什么
前者调用的是一个函数,当点击的时候可以执行函数
而后者只是将函数运行后的值赋值给了a,所以当点击的时候并不会执行函数
9.按时间顺序排序的日志信息,如何快速找到指定时间的日志。时间复杂度是多少
这个是数据结构中的日志信息,有兴趣的同学可以自行百度
10.写一个fiter函数执行器,第一个参数为filter函数,剩余的参数传入filter执行,并返回结果,exeFilter()
首先看看js filter()的用法,
array.filter(function(currentValue,index,arr), thisValue)
参数 描述
-
function(currentValue, index,arr)
- currentValue 必须。当前元素的值
- index 可选。当前元素的索引值
- array 可选。当前元素属于的数组对象
- thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"
var ages = [32, 33, 16, 40];
function exeFilter(age) {
return age >= 18;
}
function myFunction() {
document.getElementById("demo").innerHTML = ages.filter(exeFilter);
}
11.这题是一个浏览器,console中报错信息,要求一条条解释,图片没拍到,可以自行脑补
面试
宣讲会6点开始,晚饭没吃,就跑去听宣讲会了,原本以为7,8点就能结束,但是宣讲+笔试+面试,硬是拖到了10点钟才吃上晚饭。
废话不多说,讲重点
面试排队轮到我了,首先和面试官打个招呼,简历递给他,他直接开始看简历了,没说啥,我就自己先进行了自我介绍,讲了下基本情况,以及一些实习经历
接着面试官开始问问题,一上来就直接问的框架,看来框架还是挺重要
面试官:你的简历上写了angular.js,你能讲讲angular吗?
由于临时接到的宣讲会通知,框架还没整理准备好,只说了一些简单的知识,加上单页面的跳转。然后我强调了vue,但是面试官嗯了一下,没太在意,就过去了。应该公司侧重angular吧。感觉这一问题没回答好
接着就是照简历来问了
gulp
- 面试官:你能说说gulp吗?
- 我:gulp是前端工程化开发工具,能够极大的增强工作流程
- 面试官:那你主要用gulp干了哪些具体的事呢?
- 我:主要用gulp进行图片压缩,less,sass编译,es6编译为es5以及其他自动化工作
- 面试官:那gulp有哪些api呢?
-
我:
- gulp.task 主要就是运用这个进行任务的创建,其他还有* gulp.src 用来查找一个或多个文件
- gulp.watch用来监听文件的变化,
- gulp.dest指定文件输出的文件夹路径
- 面试官:嗯好
es6
- 面试官:你能讲一下let和var的区别吗
- 我:var定义的变量有时候会泄露到全局,有一定的影响,而es6的let可以解决这个问题,let相当与赋予了一个块级作用域,let定义的变量只能在该作用域中起作用
- 面试官:嗯好的
响应式
- 面试官:你能讲一下你对响应式的理解吗
-
我:
- 响应式主要是文档呈现方式能够随浏览器宽度的改变而随之改变。
- 我主要是运用bootstrap的栅格化系统加上媒体查询来达到这一目的。
- 另外我还了解了fundation, fundation和bootstrap的主要区别我觉得是,fundation是能够随着浏览器大小改变,实时改变文档样式,而且具有像css3中transition一样的过渡效果,而bootstrap是当浏览器宽度大小改变到一个固定值的时候,文档样式产生响应改变
- 面试官:嗯好的
'=='和'==='的区别
- 面试官:你能讲讲'=='和'==='的区别
- 我:'=='是有强制类型转换的,'==='没有转换
- 面试官:嗯好(接着手写了一个题目)
a={a:1}
b={b:1}
- 面试官:你能说说a==b和a===b这两个是真还是假吗
- 我:(一开始没听懂面试官的意思,让他有复述了一遍,然后看着题目还是一脸懵逼,没看懂啥意思,稍微想了下)
- 面试官:能给我正确答案了吗?
- 我:(感觉有套路)我随便答了下,a==b是true,a===b是false
- 面试官:好的,你能解释一下吗
- 我:(含糊的说)好像对象typeof返回的值是什么什么
后来想想,其实这是个很容易的题目啊,我竟然没想到,我以为他靠考的重点是==和===,往这钻去了,
其实这道题考的是引用类型,引用类型是存在堆中的,虽然a和b的值是一样的,但是存放在栈中的是指向不同堆内存的指针,所以不存在类型转换,那么两者都应该是false
让我总结
- 面试官:差不多到这了,你能总结一些这次面试吗
- 我:我觉得我的基础知识还需要多巩固,多看看
- 面试官:嗯,好的
收尾(因为当时已经很晚了,差不多晚上10点左右了,面试感觉有点赶)
- 面试官:面试到这差不多了,你有什么问题想问我的吗?
- 我:(想了下这是个套路,还好有准备)公司目前所主要用的框架是什么呢?
- 面试官:我们有用vue和angular,主要用angular
- 我:angular1和angular2差别挺大的
- 面试官:是的,但是angular2-angular4都差不多
- 我:我的表现如何呢,有哪些不足的地方呢?
- 面试官:不要太紧张了,放松点
- 我:哦,好的,那技术方面呢,有什么不足的吗
- 面试官:基础要看,框架也要再多学习多看
- 我:嗯好的
面试到此结束。等待通知中。。。
感觉面试总体还好吧,能答的都答了,就是那道基础题坑了
二面也结束了,没有回答好,被刷了,一方面没有经验,一方面很多东西不常用忘记了。
二面具体问题请看 前端面试经历
最后有什么不对的地方,欢迎指正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。