文章目录

  • 1⃣️项目1:Chrome插件
    • 作用和怎么想到的:
    • 目录树以及作用:
      • 前端:
        • 扩展程序的扩展页面和将信息发到页面其他js的操作:popup.html、popup.js
        • 得到popup的跳转指令进行定向跳转的操作:all_content.js
        • 在教务处域名下获取验证码并识别以及获取账号密码模拟点击登录的操作:content.js(验证码)和getkey_content.js(账号密码并点击)
      • 后端:
        • Flask相关
        • 图像识别相关
          • img_to_one_zero.py
          • captcha_to_text.py
    • 相关技术点:
      • css伪类
      • 验证码图片怎么获取的
      • 如果返回的验证码字符串有问题或者是网络报错(非200)
      • 扩展程序popup是怎样传递消息给页面的
      • 页面怎么接收popup的信息呢,并且怎样实现只要在每个页面点击教务处登录按钮就能跳转页面登录的呢
  • 2⃣️项目2(基于数据挖掘和语义情感分析的商品指标评价研究)
  • 3⃣️前端面试复习笔记:
    • 输入一个url到页面呈现到浏览器上的全过程
    • 怎样以对象为构造函数创建一个对象
    • 设计模式
    • Js的新规范
    • 你平时开发中,是怎么调试代码的?
    • 跨域解决方案:使用CORS实现跨域
    • 类的继承
    • vim
    • Linux命令
    • JS中new操作符具体做了什么事情
    • transition和animation区别
    • http状态码
    • cookie sessionStorage localStorage
    • 冒泡排序、快速排序
    • cookie的安全性
    • cookie防xxs攻击
    • 删除cookie
    • let(块中) var(上下文) const(只读)
    • 操作系统:进程调度
    • 进程和线程区别
    • XMLHttpRequest
    • GET POST PUT
    • http和https
    • 箭头函数和this
    • 改变函数内部this指针的指向函数有哪几种,他们的区别是什么
    • 一个图片url访问后怎样下载
    • 节流和防抖
    • 闭包(调用父函数变量)
    • 移动端布局
    • type="submit"表单提交理解
    • MVC和MVVM&MVP
  • 给自己挖的坑现在来填呜呜呜!(其实也不算是坑 毕竟是项目是自己之前亲手做出来的 但是之前的项目经历有的时间太久远很多技术方面的就忘了 现在只有代码)于是现在来做个阶段性总结,把之前的项目经历的一些要点和技术点总结下,以准备面试官大佬的简历提问(瑟瑟发抖~)
  • 趁有时间写点学习前端的小tips。。。(狂补!!!)

1⃣️项目1:Chrome插件

作用和怎么想到的:

因为教务处的网站比较古老,每次登陆的时候都要写验证码和账号密码,是真的很麻烦,同时之前有有关网络安全(比如什么黑进教务处或者是学生信息爬取、选课的时候模拟大规模登录把服务器搞炸啥的,但是仅仅是有这种想法,肯定是违背《网安法》的)而且插件听起来就跟生活很接近,毕竟是在Chrome浏览器上面运行的。

目录树以及作用:

前端:

扩展程序的扩展页面和将信息发到页面其他js的操作:popup.html、popup.js

<!DOCTYPE html>
<html lang="en">
<!-- 负责在任何一个标签页都可以点登录教务处的按钮或者登录服务器注册信息 -->
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>SICNU 教 务 处 登 陆 </title><style>* {margin: 20;padding: 20;}body {width: 300px;height: 250px;/* background:-webkit-linear-gradient(bottom,#FF66CC,#FF3399,#CC00FF,#9900FF,#6633FF,#3399FF,#66FFFF,#66FF99,#99FF00,#FFFF66,white); */background: -webkit-linear-gradient(bottom, #6633FF, #3399FF,#76daf3);}div {line-height: 30px;font-size: 30px;text-align: center;}p {line-height: 25px;font-size: 20px;text-align: center;}#login_click{ margin-top:40px; height:40px;}#login_click a {text-decoration:none;background:#3399FF;color:#f2f2f2;padding: 5px 20px 5px 20px;font-size:16px;font-family: 微软雅黑,宋体,Arial,Helvetica,Verdana,sans-serif;font-weight:bold;border-radius:6px;-webkit-transition:all linear 0.30s;-moz-transition:all linear 0.30s;transition:all linear 0.30s;}#login_click a:hover { background:#4d68ff; }#login_click1{ margin-top:40px; height:40px;}#login_click1 a {text-decoration:none;background:#4d68ff;color:#f2f2f2;padding: 5px 20px 5px 20px;font-size:16px;font-family: 微软雅黑,宋体,Arial,Helvetica,Verdana,sans-serif;font-weight:bold;border-radius:6px;-webkit-transition:all linear 0.30s;-moz-transition:all linear 0.30s;transition:all linear 0.30s;}#login_click1 a:hover { background:#3399FF; }.title{color: #f3a531;/*#04ff25*/margin-top:50px;font-size:30px;font-family: 微软雅黑,宋体,Arial,Helvetica,Verdana,sans-serif;font-weight:bold;border-radius:10px;}</style>
</head>
<body><div id="container" class="title"><!-- <img src="/images/sicnu.png" alt="Pulpit rock" width="30" height="30"> -->Never    Mind</div><!-- <p line-height=10px font-size=10px>填写账号和密码,一键登陆!</p> --><!-- <p></p> --><!-- <p style="margin-top:25px">账号:<input id="username" maxlength="11" type="text/javascript" name="username" /> </p> --><!-- <p style="margin-top:25px">密码:<input id="password" maxlength="20" type="password" name="password" /> </p> --><p><!-- <link rel="stylesheet" href="css/login.css" type="text/css" /> --><div style="margin-top:50px" id="login_click1"><a id="user" href="#">修改账号密码</a></div> <div style="margin-top:40px" id="login_click"><a id="jwc" href="#">登陆教务处!</a></div> </p>
</body><script src='js/popup.js'></script>
</html>
//控制两个按钮,按下就发greeting
console.log("######## popup ########")
//找到标签页tabs的id,发送greeting,等待response
function sendGreet(greet){chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {chrome.tabs.sendMessage(tabs[0].id, {greeting: greet}, function(response) {console.log(response.farewell);});})
}
document.getElementById('jwc').onclick = function()
{// if(document.getElementById('username').value!=null && document.getElementById('password').value!=null){//     var bg = chrome.extension.getBackgroundPage();//     bg.writedata(document.getElementById('username').value,document.getElementById('password').value);// }sendGreet("jwc");
}document.getElementById('user').onclick = function()
{// if(document.getElementById('username').value!=null && document.getElementById('password').value!=null){//     var bg = chrome.extension.getBackgroundPage();//     bg.writedata(document.getElementById('username').value,document.getElementById('password').value);// }sendGreet("user");
}

得到popup的跳转指令进行定向跳转的操作:all_content.js

//接收popup的greeting并跳转
console.log("######## all_content #########");
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {if (request.greeting == "jwc") {sendResponse({farewell: "request hello success"});console.log('ON CLICK message success');if (window.location.href.indexOf("202.115.194.60") < 0 ) {console.log("----------------jump----------------");window.open("http://202.115.194.60/");window.close();}   }if (request.greeting == "user") {sendResponse({farewell: "request hello success"});console.log('ON CLICK message success');window.open("http://49.232.13.120:1111/");window.close(); }}
);

在教务处域名下获取验证码并识别以及获取账号密码模拟点击登录的操作:content.js(验证码)和getkey_content.js(账号密码并点击)

//发送验证码图片和收到验证码字符串
console.log("######## content #########");
window.onload = function() { if(!document.getElementById("tbPassWord")){}else{let imgsrc = "http://202.115.194.60/(S(2uetwrdaij231tdylwslokfu))/CheckCode.aspx";let image = new Image();image.src = imgsrc;image.setAttribute("crossOrigin", "anonymous");image.onload = function () {let canvas = document.createElement("canvas");canvas.width = image.width;canvas.height = image.height;let context = canvas.getContext("2d");context.drawImage(image, 0, 0, image.width, image.height);let url = canvas.toDataURL("image/png");  console.log(url);  var imgbase64 = url.substring(22);url = "http://49.232.13.120:1111/sendbase64";var request = new XMLHttpRequest();try{request.open("POST",url); request.send(imgbase64);}catch(e){alert("哼唧 = =# 服务器繁忙请重试的啦!");}request.onload = function() {if(request.status == 200 && request.responseText.length == 4) {document.getElementById("txtCode").value = request.responseText;console.log(request.responseText);}else{window.open("http://202.115.194.60/");window.close();}}}}
} 
//获取密码用户名并提交
console.log("######## getkey_content #######");
function getusername(){var url = "http://49.232.13.120:1111/getusername"var request = new XMLHttpRequest();try{request.open("GET",url);request.send();}catch(e){alert("哼唧 = =# 服务器繁忙请重试的啦!");}request.onload = function(){if(request.status == 200 && request.response!=""){console.log(request.response);setTimeout(document.getElementById("tbUserName").value = request.responseText,1000);document.getElementById("btnLogin").click();}}
}
function getpassword(){var url = "http://49.232.13.120:1111/getpassword"var request = new XMLHttpRequest();try{request.open("GET",url);request.send();}catch(e){alert("哼唧 = =# 服务器繁忙请重试的啦!");}request.onload = function(){if(request.status == 200 && request.response!=""){console.log(request.response);setTimeout(document.getElementById("tbPassWord").value = request.responseText,1000);document.getElementById("btnLogin").click();}else {alert("你还没在插件登陆页面设置账号密码哦!\nQAQ或者是填写错误!\n点击跳转至登陆页面吧!");window.open("http://49.232.13.120:1111/");window.close();}}
}
for(var i = 0;i<1;i++){setTimeout(getusername,1000);
}
for(var i = 0;i<1;i++){setTimeout(getpassword,1000);
}

后端:

Flask相关

from flask import Flask, request,render_template
import base64
import filemakerapp = Flask(__name__)  # 创建�?个服务,赋�?�给APP@app.route('/', methods=['get', 'post'])  # 指定接口访问的路径,支持�?么请求方式get,post
def wait():return render_template('index.html')@app.route('/sendbase64', methods=['get', 'post'])  # 指定接口访问的路径,支持�?么请求方式get,post
def response():url = str(request.get_data())[1:]print(url)if url:ip = str(request.remote_addr)try:getbase64 = base64.b64decode(url)except:return urltext = filemaker.gettext(ip, getbase64)print(text)return textelse:return "NULL"@app.route('/sendusername', methods=['get', 'post'])
def sendusername():username = str(request.get_data())[1:]print(username)if username:ip = str(request.remote_addr)us = filemaker.maketxt(ip + "_username", username)print("us:" + us)return "us:" + uselse:return "NULL"@app.route('/sendpassword', methods=['get', 'post'])
def sendpassword():password = str(request.get_data())[1:]print(password)if password:ip = str(request.remote_addr)pw = filemaker.maketxt(ip + "_password", password)print("pw:" + pw)return "pw:" + pwelse:return "NULL"@app.route('/getpassword', methods=['get', 'post'])
def getpassword():ip = str(request.remote_addr)if ip:password = filemaker.getpassword(ip)[1:-1]print("password" + password)return passwordelse:return "NULL"@app.route('/getusername', methods=['get', 'post'])
def getusername():ip = str(request.remote_addr)if ip:username = filemaker.getusername(ip)[1:-1]print("username" + username)return usernameelse:return "NULL"if __name__ == '__main__':app.run(host='0.0.0.0', port=1111)
from PIL import Image
import img_to_one_zero
import captcha_to_textdef gettext(ip, getbase64):file = open(ip + ".png", 'wb')file.write(getbase64)file.close()img = Image.open(ip + ".png")img_to_one_zero.ImgtoZeroOne(img, str(ip + ".png"))text = captcha_to_text.textpredict(ip + ".png")print(text)return textdef maketxt(ip, data):file = open(ip + ".txt", 'w')file.write(data)file.close()return "done"def getpassword(ip):file = open(ip + "_password.txt", 'r')password = file.readline()return password;def getusername(ip):file = open(ip + "_username.txt", 'r')password = file.readline()return password;

图像识别相关

img_to_one_zero.py
# !/usr/bin/env python
# -*- coding:utf-8 -*-
# author: haotian time:2019/10/
from PIL import Image
import cv2
import matplotlib.pyplot as pltdef sum_9_region_new(img, x, y):"""9邻域框,以当前点为中心的田字框,黑点个数:param x::param y::return:"""# 判断图片的长宽度下限cur_pixel = img.getpixel((x, y))  # 当前像素点的值width = img.widthheight = img.heightif cur_pixel == 1:  # 如果当前点为白色区域,则不统计邻域值return 0if y == 0:  # 第一行if x == 0:  # 左上顶点,4邻域# 中心点旁边3个点sum = cur_pixel \+ img.getpixel((x, y + 1)) \+ img.getpixel((x + 1, y)) \+ img.getpixel((x + 1, y + 1))return 4 - sumelif x == width - 1:  # 右上顶点sum = cur_pixel \+ img.getpixel((x, y + 1)) \+ img.getpixel((x - 1, y)) \+ img.getpixel((x - 1, y + 1))return 4 - sumelse:  # 最上非顶点,6邻域sum = img.getpixel((x - 1, y)) \+ img.getpixel((x - 1, y + 1)) \+ cur_pixel \+ img.getpixel((x, y + 1)) \+ img.getpixel((x + 1, y)) \+ img.getpixel((x + 1, y + 1))return 6 - sumelif y == height - 1:  # 最下面一行if x == 0:  # 左下顶点# 中心点旁边3个点sum = cur_pixel \+ img.getpixel((x + 1, y)) \+ img.getpixel((x + 1, y - 1)) \+ img.getpixel((x, y - 1))return 4 - sumelif x == width - 1:  # 右下顶点sum = cur_pixel \+ img.getpixel((x, y - 1)) \+ img.getpixel((x - 1, y)) \+ img.getpixel((x - 1, y - 1))return 4 - sumelse:  # 最下非顶点,6邻域sum = cur_pixel \+ img.getpixel((x - 1, y)) \+ img.getpixel((x + 1, y)) \+ img.getpixel((x, y - 1)) \+ img.getpixel((x - 1, y - 1)) \+ img.getpixel((x + 1, y - 1))return 6 - sumelse:  # y不在边界if x == 0:  # 左边非顶点sum = img.getpixel((x, y - 1)) \+ cur_pixel \+ img.getpixel((x, y + 1)) \+ img.getpixel((x + 1, y - 1)) \+ img.getpixel((x + 1, y)) \+ img.getpixel((x + 1, y + 1))return 6 - sumelif x == width - 1:  # 右边非顶点# print('%s,%s' % (x, y))sum = img.getpixel((x, y - 1)) \+ cur_pixel \+ img.getpixel((x, y + 1)) \+ img.getpixel((x - 1, y - 1)) \+ img.getpixel((x - 1, y)) \+ img.getpixel((x - 1, y + 1))return 6 - sumelse:  # 具备9领域条件的sum = img.getpixel((x - 1, y - 1)) \+ img.getpixel((x - 1, y)) \+ img.getpixel((x - 1, y + 1)) \+ img.getpixel((x, y - 1)) \+ cur_pixel \+ img.getpixel((x, y + 1)) \+ img.getpixel((x + 1, y - 1)) \+ img.getpixel((x + 1, y)) \+ img.getpixel((x + 1, y + 1))return 9 - sumdef collect_noise_point(img, n):'''收集所有的噪点'''noise_point_list = []for x in range(img.width):for y in range(img.height):res_9 = sum_9_region_new(img, x, y)if (0 < res_9 < n) and img.getpixel((x, y)) == 0:  # 找到孤立点pos = (x, y)noise_point_list.append(pos)return noise_point_listdef remove_noise_pixel(img, noise_point_list):'''根据噪点的位置信息,消除二值图片的黑点噪声'''for item in noise_point_list:img.putpixel((item[0], item[1]), 1)def get_bin_table(threshold):'''获取灰度转二值的映射table,0表示黑色,1表示白色'''table = []for i in range(256):if i < threshold:table.append(0)else:table.append(1)return tabledef remake(guess_img, much_num, n, i):"""guess_img:传入图片文件much_num: 阈值,控制二值化程度,自行调整(不能超过256)n:九宫格法去除像素点周围点的数量(推荐6和7)"""imgry = guess_img.convert('L')table = get_bin_table(much_num)binary = imgry.point(table, '1')noise_point_list = collect_noise_point(binary, n)remove_noise_pixel(binary, noise_point_list)binary.save(i)def ImgtoZeroOne(image, i):"""image:传入处理识别图片i:第i个图片"""image = image.resize((120, 50))  # 根据图片长宽改正,实验表明以原图大小处理后识别概率比较高remake(image, 235, 8, i)Image.open(i).save(i)image = Image.open(i)image = image.resize((120, 50))  # 根据图片长宽改正,实验表明以原图大小处理后识别概率比较高remake(image, 120, 6, i)Image.open(i)image = Image.open(i)image = image.resize((120, 50))  # 根据图片长宽改正,实验表明以原图大小处理后识别概率比较高remake(image, 100, 4, i)Image.open(i)image = Image.open(i)image = image.resize((120, 50))  # 根据图片长宽改正,实验表明以原图大小处理后识别概率比较高remake(image, 80, 2, i)
captcha_to_text.py
from keras.models import load_model
from helpers import resize_to_fit
from imutils import paths
import numpy as np
import imutils
import cv2
import pickle
import tensorflow as tfMODEL_FILENAME = "captcha_model.hdf5"
MODEL_LABELS_FILENAME = "model_labels.dat"# Load up the model labels (so we can translate model predictions to actual letters)
with open(MODEL_LABELS_FILENAME, "rb") as f:lb = pickle.load(f)# Load the trained neural network
model = load_model(MODEL_FILENAME)def textpredict(image_file):# loop over the image paths# image_file = ""# Load the image and convert it to grayscaleimage = cv2.imread(image_file)image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# Add some extra padding around the imageimage = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE)# threshold the image (convert it to pure black and white)thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]# find the contours (continuous blobs of pixels) the imagecontours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# Hack for compatibility with different OpenCV versions# contours = contours[0] if imutils.is_cv2() else contours[1]contours = contours[1] if imutils.is_cv3() else contours[0]letter_image_regions = []# Now we can loop through each of the four contours and extract the letter# inside of each onefor contour in contours:# Get the rectangle that contains the contour(x, y, w, h) = cv2.boundingRect(contour)# Compare the width and height of the contour to detect letters that# are conjoined into one chunkif w / h > 1.25:# This contour is too wide to be a single letter!# Split it in half into two letter regions!half_width = int(w / 2)letter_image_regions.append((x, y, half_width, h))letter_image_regions.append((x + half_width, y, half_width, h))else:# This is a normal letter by itselfletter_image_regions.append((x, y, w, h))# Sort the detected letter images based on the x coordinate to make sure# we are processing them from left-to-right so we match the right image# with the right letterletter_image_regions = sorted(letter_image_regions, key=lambda x: x[0])# Create an output image and a list to hold our predicted letterspredictions = []# loop over the lekttersfor letter_bounding_box in letter_image_regions:# Grab the coordinates of the letter in the imagex, y, w, h = letter_bounding_box# Extract the letter from the original image with a 2-pixel margin around the edgeletter_image = image[y - 2:y + h + 2, x - 2:x + w + 2]# Re-size the letter image to 20x20 pixels to match training dataletter_image = resize_to_fit(letter_image, 20, 20)# Turn the single image into a 4d list of images to make Keras happyletter_image = np.expand_dims(letter_image, axis=2)letter_image = np.expand_dims(letter_image, axis=0)# Ask the neural network to make a predictionprediction = model.predict(letter_image)# Convert the one-hot-encoded prediction back to a normal letterletter = lb.inverse_transform(prediction)[0]predictions.append(letter)# Print the captcha's textcaptcha_text = "".join(predictions)return captcha_text

相关技术点:

css伪类

css伪类

验证码图片怎么获取的

本来是想着直接从浏览器缓存里面获取第一次请求的图片的,但是由于权限问题属实没有找到方法,于是就只好重新手动模拟请求一个验证码图片咯。

let imgsrc = "http://202.115.194.60/(S(2uetwrdaij231tdylwslokfu))/CheckCode.aspx";
let image = new Image();
image.src = imgsrc;
image.setAttribute("crossOrigin", "anonymous");//关闭防画布污染策略
image.onload = function () {let canvas = document.createElement("canvas");canvas.width = image.width;canvas.height = image.height;let context = canvas.getContext("2d");context.drawImage(image, 0, 0, image.width, image.height);let url = canvas.toDataURL("image/png");  console.log(url);  var imgbase64 = url.substring(22);url = "http://49.232.13.120:1111/sendbase64";var request = new XMLHttpRequest();try{request.open("POST",url); request.send(imgbase64);}catch(e){alert("哼唧 = =# 服务器繁忙请重试的啦!");}
  • canvas绘图的跨域问题
  • 转成base64:canvas.toDataURL(“image/png”); if something wrong

如果返回的验证码字符串有问题或者是网络报错(非200)

  • http状态码
request.onload = function() {if(request.status == 200 && request.responseText.length == 4) {document.getElementById("txtCode").value = request.responseText;console.log(request.responseText);}else{window.open("http://202.115.194.60/");window.close();//刷新页面重来}}

扩展程序popup是怎样传递消息给页面的

function sendGreet(greet){chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {chrome.tabs.sendMessage(tabs[0].id, {greeting: greet}, function(response) {console.log(response.farewell);});})
}

tab选择器

然后就可以在popup的js里给页面的content-script发信息啦

document.getElementById('jwc').onclick = function()sendGreet("jwc"); # 这里就可以给页面发送信息啦!
}

页面怎么接收popup的信息呢,并且怎样实现只要在每个页面点击教务处登录按钮就能跳转页面登录的呢

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {if (request.greeting == "jwc") {sendResponse({farewell: "request hello success"});console.log('ON CLICK message success');if (window.location.href.indexOf("202.115.194.60") < 0 ) {console.log("----------------jump----------------");window.open("http://202.115.194.60/");window.close();}   }if (request.greeting == "user") {sendResponse({farewell: "request hello success"});console.log('ON CLICK message success');window.open("http://49.232.13.120:1111/");window.close(); }}
);

2⃣️项目2(基于数据挖掘和语义情感分析的商品指标评价研究)


主要收获是:
在GitHub上找到了类似的网站评论语义情感分析的代码,用的是LSTM时间循环神经网络,于是我就git clone然后改了改调用了下,训练了模型然后给那道题的评论进行情感分析;
一些数据处理的方式:就比如纯手写了一个解决“3/14/2020这种日月年中间还有个符号的,在excel里面完全找不到排序方式”的python代码,主要思想是找到那串字符的两个“/”的位置;
然后就是一些数学算法的python实现。

3⃣️前端面试复习笔记:

输入一个url到页面呈现到浏览器上的全过程

详细版

  1. DNS解析
  2. TCP连接建立(三次握手,四次挥手)
    TCP(Transmission Control Protocol)传输控制协议
    TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
    位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)Sequence number(顺序号码) Acknowledge number(确认号码)
    第一次握手(A向B请求建立联机):主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1就知道A要求建立联机;
    第二次握手(B向A请求确认联机):主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1随机产生seq=7654321的包;
    第三次握手(A向B回复确认联机的情况):主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功
    FTP协议及时基于此协议。

    为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
  3. 加载文件(HTML,JS,CSS)
  4. 渲染页面(生成DOMtree,CSSrule,结合成render tree ,页面布局,元素绘制)

怎样以对象为构造函数创建一个对象

设计模式

Js的新规范

你平时开发中,是怎么调试代码的?

console.log , alert(),其他语言设置断点

跨域解决方案:使用CORS实现跨域

跨域

类的继承

vim

Linux命令

Linux命令

JS中new操作符具体做了什么事情

var a = new A();
1.创建一个空对象 : var obj={}
2.继承A原型链: obj=A.prototype
3.将this指向obj执行A :A.call(obj)
或者

  1. 创建一个全新的对象;
  2. 把这个对象内置的的原型引用指向到构造函数的prototype属性所引用的对象上;
  3. 将函数中的this对象指向这个全新的对象;
  4. 如果函数return出去的是一个引用类型的值,则返回这个值;否则就return这个全新的对象。

transition和animation区别

Transition:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画。但只有两个关键贞。开始,结束。 Animation:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画。可以设置多个关键贞。 Transition与Animation区别: transition需要触发一个事件,而animation在不需要触发任何事件的情况下也可以显式的随着时间变化来改变元素css的属性值,从而达到一种动画的效果。 Transition: transition属性是一个简单的动画属性,非常简单非常容易用。可以说它是animation的简化版本,是给普通做简单网页特效用的。
transition和animation都随着时间改变元素的属性值

transition注重过渡 需要一个触发事件如鼠标移动等 transition只有开始和结束两帧 即from…to

animation可以一帧一帧执行 不需要事件的触发

http状态码

cookie sessionStorage localStorage


cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递
cookie数据还有路径(path)的概念,可以限制。cookie只属于某个路径下。
存储大小限制也不同
cookie数据不能超过4K,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如回话标识。
webStorage虽然也有存储大小的限制,但是比cookie大得多,可以达到5M或更大
数据的有效期不同
sessionStorage:仅在当前的浏览器窗口关闭有效;
localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
cookie:只在设置的cookie过期时间之前一直有效,即使窗口和浏览器关闭
作用域不同
sessionStorage:不在不同的浏览器窗口都是共享,即使是同一个页面;
localStorage:在所有同源窗口都是共享的;
cookie:也是在所有同源窗口都是共享的

冒泡排序、快速排序

都是交换排序 所以时间复杂度都是O(n2)
冒泡:通过从头的交换找出相对最大的,排到后面
快速:设置某个标准,划分比他大和比他小的两部分;一直循环迭代到左右两边只有1个值

cookie的安全性

cookie防xxs攻击

对重要的cookie设置httpOnly,防止客户端通过document.cookie读取cookie

删除cookie

设置往前一点的时间

var date = new Date();
date.setDate(date.getDate() - 1);//真正的删除

let(块中) var(上下文) const(只读)

操作系统:进程调度

个人认为实用性排序:634215
1、先来先服务,就是按照顺序来;
2、短作业优先,就是按照时间花费排序,最短的最先做;
3、优先权调度,就是在上面两个方式上,如果遇到优先权高的,就do it,或者提前设置任务优先权,然后越高越优先;
4、高响应比优先度,因为短作业优先算法不能照顾长的作业,也就是长的作业一直要等到最后做,所以改进方式就是,长作业的优先度和长作业的等待时间成正比,有长作业超过此时的短作业的优先度就do it;
5、时间片轮转法,就是给每个作业分配相同的时间片,就比如45分钟的课分5份9分钟,固定时间内分别做一个作业,再循环;
6、多级反馈队列调度,设置多个就绪任务队列,赋予不同优先级,从高到低排,但是越高优先度的分配的执行时间片越小,如果第一个优先级最高的任务在第一个短的时间片没做完,那么转而跳到第二个优先级的任务和第二个相对较长的时间片,在这个时间里面先做第二个任务,如果第二个任务做完有剩余时间,那么就做之前的第一个没做完的任务,如果第一个任务在这个时间内还是没做完,那么转而到第三个任务和时间片以此类推,也就是说这个优先度高但是执行时间长的任务在不影响其他任务完成的情况下,用每个时间片的剩余时间执行。

进程和线程区别

1、进程:系统进行资源分配和调度的基本单位
线程:操作系统能够进行运算调度的最小单位
2、进程:进程是程序的基本执行实体
线程:程序独立调度和分派的基本单位
3、进程:描述系统内部各道程序的活动规律引进的一个概念
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。
在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。

XMLHttpRequest

XMLHttpRequest
在不重新加载页面的情况下更新网页
在页面已加载后从服务器请求数据
在页面已加载后从服务器接收数据
后台向服务器发送数据

var url = "http://49.232.13.120:1111/getpassword"var request = new XMLHttpRequest();try{request.open("GET",url);request.send();}catch(e){alert("哼唧 = =# 服务器繁忙请重试的啦!");}

GET POST PUT

http请求方法
GET 发送一个请求来取得服务器上的某一资源
POST 向URL指定的资源提交数据或附加新的数据
PUT 跟POST方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT指定了资源在服务器上的位置,而POST没有

http和https

链接
超文本传输协议
加不加密
http1.0只能传html 后面可以传js css了

箭头函数和this

  • 箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
//ES5 Version
var getCurrentDate = function (){return new Date();
}//ES6 Version
const getCurrentDate = () => new Date();

在本例中,ES5 版本中有function(){}声明和return关键字,这两个关键字分别是创建函数和返回值所需要的。在箭头函数版本中,我们只需要()括号,不需要 return 语句,因为如果我们只有一个表达式或值需要返回,箭头函数就会有一个隐式的返回。

//ES5 Version
function greet(name) {return 'Hello ' + name + '!';
}//ES6 Version
const greet = (name) => `Hello ${name}`;
const greet2 = name => `Hello ${name}`;

我们还可以在箭头函数中使用与函数表达式和函数声明相同的参数。如果我们在一个箭头函数中有一个参数,则可以省略括号。

const getArgs = () => argumentsconst getArgs2 = (...rest) => rest

箭头函数不能访问arguments对象。所以调用第一个getArgs函数会抛出一个错误。相反,我们可以使用rest参数来获得在箭头函数中传递的所有参数。

const data = {result: 0,nums: [1, 2, 3, 4, 5],computeResult() {// 这里的“this”指的是“data”对象const addAll = () => {return this.nums.reduce((total, cur) => total + cur, 0)};this.result = addAll();}
};

箭头函数没有自己的this值。它捕获词法作用域函数的this值,在此示例中,addAll函数将复制computeResult 方法中的this值,如果我们在全局作用域声明箭头函数,则this值为 window 对象。

  • this

改变函数内部this指针的指向函数有哪几种,他们的区别是什么

bind 返回一个新的函数, 第一个参数是改变this指向的对象 直接传参
apply 对函数的直接调用, 第一个参数是改变this指向的对象 第二个参数用数组包裹
call 对函数直接调用,第一个参数是改变this指向的对象 直接传参

一个图片url访问后怎样下载

右击可下载
跨域情况下 关闭画布污染策略 canvas.drawImage canvas.toDataURL

节流和防抖

链接

闭包(调用父函数变量)

闭包形成条件
条件一 函数嵌套
条件二 子函数访问父函数变量
条件三 外部访问子函数 可以获取函数作用域的变量

优点:可以从函数外部访问函数内部变量、保留变量不会被销毁,缺点:不会被垃圾回收机制回收

移动端布局

移动端布局方式(一般采用自适应布局),移动端适配:
a.流体布局+少量响应式
b.基于rem的布局
c.弹性布局。响应式布局很少应用在移动端,因为工作量大难以维护。
流体布局:尺寸使用百分比而不是像素,能针对浏览器的窗口宽度进行伸缩。
基于rem的布局 :rem是相对于根元素的字体大小单位,是一个相对元素
弹性布局:Flex容器、Flex项目、水平的主轴(main axis)、垂直的交叉轴(cross axis)。
设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
容器上设置的属性:
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
http://www.runoob.com/w3cnote/flex-grammar.html

项目上设置的属性
order
flex-grow
flex-shrink
flex-basis
flex
align-self

type="submit"表单提交理解

type="submit"表单提交理解

MVC和MVVM&MVP

参考链接

  • MVC的controller:
    数据和视图的协调者,也就是在Controller里面把Model的数据赋值给View来显示(或者是View接收用户输入的数据然后由Controller把这些数据传给Model来保存到本地或者上传到服务器)
    MVP(Model-View-Presenter)是MVC的改良模式,由IBM的子公司Taligent提出。和MVC的相同之处在于:Controller/Presenter负责业务逻辑,Model管理数据,View负责显示只不过是将 Controller 改名为 Presenter,同时改变了通信方向。

  • MVP特点:

M、V、P之间双向通信。
View 与 Model 不通信,都通过 Presenter 传递。Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。
View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,这样就可以重用。不仅如此,还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试–从而不需要使用自动化的测试工具。

  • 在MVP中,View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部。
  • 在MVC中,View会直接从Model中读取数据而不是通过 Controller。

MVP优点:

模型与视图完全分离,我们可以修改视图而不影响模型;
可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;
我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。
MVP缺点:

视图和Presenter的交互会过于频繁,使得他们的联系过于紧密。也就是说,一旦视图变更了,presenter也要变更。

MVP应用:
可应用与Android开发。

三张图

一面准备:项目经历、开放问题回答、基础相关推荐

  1. 大学计算机应用基础项目考核答案,2017江苏开放大学计算机应用基础第三次形成性考核作业附答案...

    2017江苏开放大学计算机应用基础第三次形成性考核作业附答案 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 江苏开放大学形成性考核作业 ...

  2. 看到这个机器学习项目经历,面试官跟我聊嗨了

    "语言智能是人工智能皇冠上的明珠,如果语言智能能实现突破,跟它同属认知智能的知识和推理就会得到长足的发展,就能推动整个人工智能体系,有更多的场景可以落地." -微软亚洲研究院副院长 ...

  3. 做了两年前端开发,平时就是拿 Vue 写写页面和组件,简历的项目经历应该怎么写得好看?

    无意间在知乎看见的,感觉讲得很有道理.看原文点这里  ------>  做了两年前端开发,平时就是拿 Vue 写写页面和组件,简历的项目经历应该怎么写得好看? 2年经验做的东西没什么技术含量,应 ...

  4. 【面试简历】软件测试,没有项目经历,简历怎么写?

    有测试相关的问题都可以给我留言,我们可以互相交流. 没有项目经历,怎么样找到第一份工作.这个问题对大部分转行的同学来说,应该都比较困难.所以我们今天就来聊一聊. 找工作嘛,其实就是一个供求关系,我们首 ...

  5. 简历上的项目经历怎么写 ?这 3 条原则不可忽视 !

    阅读本文大概需要 5 分钟. 作者:黄小斜 作为一个程序员,想必大家曾经都做过一些项目,可能现在手头上也还有一些项目. 不过还是有很多学生朋友来问我"没有项目怎么办",诚然,确实有 ...

  6. python工程师简历项目经验怎么写_简历上的项目经历怎么写 ?这 3 条原则不可忽视 !...

    阅读本文大概需要 5 分钟. 作者:黄小斜 作为一个程序员,想必大家曾经都做过一些项目,可能现在手头上也还有一些项目. 不过还是有很多学生朋友来问我"没有项目怎么办",诚然,确实有 ...

  7. 阿里算法,浙大博士带你写项目经历!

    Datawhale干货 作者:罗浩,阿里巴巴,浙江大学博士 简历模块 校招应届生的简历主要包括:基本信息.教育背景.工作/实习经历.科研/项目经历.荣誉/获奖称号,组织/社团经历以及其他个人评价等.其 ...

  8. python简介怎么写-Python开发工程师岗位项目经历怎么写

    项目经历(案例一) 项目时间:2017-01到2011-10 项目名称:引物自动化设计软件 项目描述: 项目介绍 这个软件开发原因是因为随着每日数据分析量的加大,组内人员较少,对引物设计这种工作变成了 ...

  9. NLP面试时,项目经历要怎么讲?

    很多粉丝问我,NLP算法工程师面试的时候.或者在简历中,项目经历要怎么讲? 我去请教了在BAT大厂长期担任面试官的大佬,并结合自身的一些经历,统一给大家回答一下. 一.项目介绍稿 针对自己做过的项目, ...

最新文章

  1. GEO,以GSM2309041这套数据为例,找到需要的sra数据,SRX2159543
  2. pipe 双管道 简易实现代码
  3. 每日一皮:当你要下班的时候,突然测试叫住了你...
  4. python 语言教程(3)变量
  5. 怎么求导来着?别费劲了,试试这个Python的通用求导法
  6. CCNA初认识——ACL命令
  7. java二进制 字节数组 字符 十六进制 BCD编码转换
  8. MATLAB 画图 x轴换成 字符串
  9. 竹林蹊径:深入浅出Windows驱动开发
  10. web前端大一实训 HTML+CSS+JavaScript王者荣耀(60页) web课程设计网页规划与设计 HTML期末大作业 HTML网页设计结课作业...
  11. win10下如何检测快捷键被被哪个进程占用
  12. 全自动过滤器:全自动自清洗过滤器对给排水总结的经验
  13. Skydio 2在行动中的第一响应者部署显示了无人机自主权
  14. 手机恢复出厂设置难防泄密:微信聊天记录可恢复
  15. 必收藏的实用网站(一)
  16. 图片折腾的经历——文件批处理、爬虫、图片工具等
  17. Tita 如何支持企业完成 360 环评
  18. 征服账号服务器,最新中文征服服务端(带架设教程+客户端补丁+需要的工具)10.13日更新...
  19. 浅谈PLC电力线载波技术
  20. python周环比增长率怎么算_平均增长速度可以根据各个环比增长速度直接求得。()...

热门文章

  1. linux常用加速器使用
  2. php 根据时间获取二十四节气,返回json
  3. Apache Hudi数据湖的Cleaning服务
  4. ArcGIS Pro创建文件地理数据库、要素数据集、要素类
  5. HTML+CSS基础面试题总结
  6. Autodesk软件网络授权破解
  7. Debian9+openmediavault4搭建全纪录
  8. Oculus Quest 2新手入门教程
  9. 如何使UDEV规则有效
  10. Abp框架从零开始(基于.Net Core 2.2) 小记(一) 为Swagger接口页添加详细注释