我参加的是今日头条的前端笔试,感觉凉凉了,看来还是要知彼知己,下次要事先预习一下对方的笔试题,先从最后一题开始回忆吧,我尽量回忆全一点,希望能够帮到广大网友,我自己也要加进补一下数据结构,算法方面的知识了,还有网络通信方面的知识了。
最后一题有5道选择题:
第一道就是关于入栈和出栈问题:
A,B,C,D,E五个元素,按照顺序进栈,进栈是可以出栈,问有几种出栈方式
答案选项如下:
a 41
b 42
c 43
d 44
一脸懵逼,看不懂,前端也会碰到这种题目,不愧是大公司,就是不一样。
第二道题是关于算法排序,时间复杂度
下面哪种算法排序,时间复杂度不超过nlogn
a 快速排序
b 冒泡排序
c 合并排序
d 堆排序
看不懂,还是计算机专业好啊。
还有就是关于网络通信方面的
tcp 和 udp 的区别,这个题目占了两道题型哦。
百度了一下:
socket、tcp、udp、http 的认识及区别
一、先来一个讲TCP、UDP和HTTP关系的
1、TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。
在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。 在传输层中有TCP协议与UDP协议。
在应用层有FTP、HTTP、TELNET、SMTP、DNS等协议。
因此,HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。
2、HTTP协议是建立在请求/响应模型上的。
首先由客户建立一条与服务器的TCP链接,并发送一个请求到服务器,
请求中包含请求方法、URI、协议版本以及相关的MIME样式的消息。
服务器响应一个状态行,包含消息的协议版本、一个成功和失败码以及相关的MIME式样的消息。
HTTP/1.0为每一次HTTP的请求/响应建立一条新的TCP链接,
因此一个包含HTML内容和图片的页面将需要建立多次的短期的TCP链接。
一次TCP链接的建立将需要3次握手。
另外,为了获得适当的传输速度,则需要TCP花费额外的回路链接时间(RTT)。
每一次链接的建立需要这种经常性的开销,而其并不带有实际有用的数据,只是保证链接的可靠性,因此HTTP/1.1提出了可持续链接的实现方法。
HTTP/1.1将只建立一次TCP的链接而重复地使用它传输一系列的请求/响应消息,因此减少了链接建立的次数和经常性的链接开销。
3、结论:
虽然HTTP本身是一个协议,但其最终还是基于TCP的。不过,目前,有人正在研究基于TCP+UDP混合的HTTP协议。
Socket是什么呢?Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,
Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,
对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
HTTP、TCP、UDP、Socket <wbr> <wbr> <wbr>(转)
二、TCP、UDP、HTTP、SOCKET之间的区别
TCP和UDP:传输层协议;
HTTP:应用层协议;
SOCKET:TCP/IP网络的API。
TCP/IP代表传输控制协议/网际协议,指的是一系列协议。
TCP和UDP使用IP协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。
TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。
TCP和UDP是FTP、HTTP和SMTP之类使用的传输层协议。
虽然TCP和UDP都是用来传输其他协议的,它们却有一个显著的不同:TCP提供有保证的数据传输,而UDP不提供。
这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点,而UDP不提供任何这样的保证。
HTTP(超文本传输协议)是利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息的协议。
客户端使用Web浏览器发起HTTP请求给Web服务器,Web服务器发送被请求的信息给客户端。
记住,需要IP协议来连接网络;TCP是一种允许我们安全传输数据的机制,使用TCP协议来传输数据的HTTP是Web服务器和客户端使用的特殊协议。
Socket 接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,用以开发TCP/IP网络上的应用程序。
三、socket、tcp、udp、http 的认识及区别
网络由下往上分为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
IP 协议对应于网络层,TCP协议对应于传输层,HTTP协议对应于应用层,三者从本质上来说没有可比性,socket则是对TCP/IP协议的封装和应用。
可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据
socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),
通过Socket,我们才能使用TCP/IP协议。
实际上,Socket跟TCP/IP协议没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。
所以说,Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,
从而形成了我们知道的一些最基本的函数接口,比如create、 listen、connect、accept、send、read和write等等
实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,
而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口
TCP连接的三次握手:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据
断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”
TCP是面向链接的,虽然说网络的不安全不稳定特性决定了多少次握手都不能保证连接的可靠性,
但TCP的三次握手在最低限度上(实际上也很大程度上保证了)保证了连接的可靠性;
而UDP不是面向连接的,UDP传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,
发送端不知道数据是否会正确接收,当然也不用重发,所以说UDP是无连接的、不可靠的一种数据传输协议
也正由于上面的特点,使得UDP的开销更小数据传输速率更高,因为不必进行收发数据的确认,所以UDP的实时性更好。
所以采用TCP传输协议的MSN比采用UDP的QQ传输文件慢,
但并不能说QQ的通信是不安全的,因为程序员可以手动对UDP的数据收发进行验证,
比如发送方对每个数据包进行编号然后由接收方进行验证啊什么的,
即使是这样,UDP因为在底层协议的封装上没有采用类似 TCP的“三次握手”而实现了TCP所无法达到的传输效率。
还有一道就是关于HTTP协议的
不记得题目选项了,但是可以大概描述一下考了什么,
主要就是靠关于HTTP描述是否正确,GET方式,POST方式等等
大概选择题就是以上这样。还是挺基础的,就是不了解的过,还真没法作答。难受,看来我要去加强我的基础知识了。
接下来就是一道算法,也是很基础的,我选择了javascript语言编写
找出输入n个数,找出出现频率大于n/2的那个数
找到网友的的答案
#include <iostream>
#include <vector>
using namespace std;
/*在大小为n的数组中寻找次数超过n/2的数*/
int find_data(vector<int> &arry)
{
int ntime = 0; //表示其中某一个数出现的次数
int result;
for(unsigned int i = 0; i < arry.size(); i++) {
if(ntime == 0) { //在i前面的数全部删除完,或者起始的时候,将arry[i]放入结果
result = arry[i];
ntime = 1; //arry[i]出现的次数为1;
} else { //如果前面有数,就说明result还没抵消完
if(result == arry[i]) //如果相等result出现的次数+1
ntime++;
else
ntime--; /*如果此时的arry[i]不等于result,则它们两个抵消,result的次数减一,由与那个数大于n/2所以它抵消不完,ntime最小为1
也就是说这个数出现的次数是大于等于n/2+1*/
}
}
return result;
}
int main()
{
vector<int> arry;
int n;
cin>>n;
for(int i = 0; i < n; i++) {
int d;
cin>>d;
arry.push_back(d);
}
int result = find_data(arry);
cout<<result;
return 0;
}
接下来就是前端知识点了
第一道就是关于闭包,this对象指向问题
var inner = "window";
function say(){
console.log(inner);
console.log(this.inner);
}
var obj1 = (function(){
var inner = '1-1';
return {
inner: "1-2",
say: function(){
console.log(inner);
console.log(this.inner);
}
}
})()
var obj2 = (function(){
var inner = '2-1';
return {
inner: "2-2",
say: function(){
console.log(inner);
console.log(this.inner);
}
}
})()
say();
obj1.say();
obj1.say = say;
obj1.say = obj2.say;
obj1.say();
打印出来还是
window
window
1-1
1-2
2-1
1-2
好的接下一题就是修改程序
下面程序按照要求依次打印出
console.log(1)
console.log(2)
console.log(3)
console.log(4)
console.log(5)
console.log(6)
console.log(7)
console.log(8)
console.log(9)
题目代码如下:
var arr = [];
for(var i=0;i<10;i++){
var fn = function(){
console.log(i);
}
arr.push(fn);
}
arr.forEach(function(fn){
fn()
})
我的修改答案如下:
方案1
for(let i=0;i<10;i++){
var fn = function(){
console.log(i);
}
arr.push(fn);
}
方案2
for(var i=0;i<10;i++){
var fn = (function(){
console.log(i);
})(i)
arr.push(fn);
}
方案3
for (var i = 0; i < 10; i++) {
arr[i] = (function(c) {
return function(){
console.log(c);
}
})(i);
}
还有一道题就是:关于算法的
找出一个数组中出现元素次数大于n/2,返回这些元素的数组
百度了一下答案,网友用的是java写的
package Interview;
/**
* 算法复杂度为O(n)
*/
public class NumCountGTHalfLen {
public static void main(String[] args) {
int[] arr={1,2,3,2,5,6,2,2,3,2,2,4,2}; //2
//int[] arr={2,2,3,3,3,6};
//int[] arr={1,2,3};
//int[] arr={1,1,2,2};
int n = numCountGTHalfLen(arr);
System.out.println(n);
}
private static int numCountGTHalfLen(int[] arr) {
int count = 1;
int num = arr[0];
for (int i = 1; i < arr.length; i++) {
if (count == 0){
count = 1;
num = arr[i];
}else {
if (arr[i]==num){
count++;
}else{
count--;
}
}
}
//到此为止求出的num有可能是所求数字,但不一定是
count = 0;
for (int i : arr) {
if (i == num) count ++;
}
return count > arr.length/2 ? num : 0;
}
}
Javascript面试题-找出数组中频率最高元素的多种方法
https://blog.csdn.net/u011277123/article/details/72819099
还有一道类似的题目就是
请添加一个所有数组都可找到一个方法findDuplicate(n)数组元素出现频率大于n,返回这些元素组成的数组
答案就是如下
Array.prototype.findDup = function (count) {
return this.reduce((re, val) => {
let index = re.findIndex(o => o.val === val)
if (index >= 0) {
re[index].count++
} else {
re.push({ count: 1, val })
}
return re
}, []).filter(o => o.count >= count).map(o => o.val)
}
以上是网友的答案
const findDuplicate = function(arr){
return (n)=>{
if(isNaN(n))return [];
n = n < 1 ? 1 : n
let resulte = [],
obj = Object.create(null)
arr.forEach(item=>{
obj[ item ] = (obj[ item ] || 0) + 1
if(obj[ item ] == n){
resulte.push(item)
}
})
return resulte
}
}([1,2,3,4,1,2,2,2])
findDuplicate(2) // [1,2]
findDuplicate(5) // []
findDuplicate(-1) // [1,2,3,4]
if (!Array.prototype.findDuplicate) {
Object.defineProperty(Array.prototype, 'findDuplicate', {
value: function (n) {
if (this === void 0 || this === null) {
throw new TypeError('this is null or not defined');
};
var t = Object(this);
var len = t.length >>> 0;
var obj = {};
var result = [];
for(let i = 0; i < len; i++) {
obj[t[i]] = (obj[t[i]] || 0)+1;
if(obj[t[i]] == n) {
result.push(t[i]);
}
}
return result;
}
});
}
各路网友都是大神啊
今天就总结到这里吧,明天再好好研究一下这些题目,好好补充一下营养。