前端面試題2
技術標籤:學習小結
1、下面程式的執行結果是什麼?請分析原因?
function f({ x = 10 } = {}, { y } = { y: 10 }) {
console.log( x + " " + y +"\n");
}
根據es6提供的引數值預設原理,undefined就是空。得到以下值。
f(); // 10 10
f( undefined, undefined ); // 10 10
f( {}, undefined ); // 10 10
f( {}, {} ); // 10 undefined
f( undefined, {} ); // 10 undefined
2.Array.from方法的作用是什麼?
將類陣列轉化為陣列。
3.Array.of和使用Array()或new Array()構建陣列例項有什麼區別
Array.of()是對new Array()的擴充套件 。不論輸入什麼,都代表的是陣列元素。
4.下面程式執行結果是什麼?
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [1,2];
push(a, 1, 2, 3)
123
5.下面程式執行結果是什麼?
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(6, 2, 3, 4, 5)
6[2345]
6.node是什麼?
Node.js 是一個基於 Chrome V8 引擎的 JavaScript 執行環境。
7.編寫程式使用ES6定義 Person類,包括類例項屬性(name,age),例項方法say()該方法
返回name和age字串
class Person{
constructor(name,age){
this.age=age
}
say(){
return '我的名字是'+this.name+'我的年齡是:'+this.age;
}
}
var p=new Person('小明',12);
console.log(p.say());
8..下面程式執行結果為:
var p=new Person();
console.log(p.__proto__===Person.prototype)
// 例項物件的__proto__指向的是建構函式的prototype
console.log(p.__proto__==Person.prototype);
結果為true。
9.下面程式正確嗎?錯在哪裡?如何改正?
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);
}
}
var cp=new ColorPoint(10,20,'red');
子類的this關鍵字根據super方法建立
應改為constructor(x,y,color){
super(x,y,color);
this.color=color;
}
10.下面程式執行結果為?
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1);
var child = new Child();
child.myMethod(2);
結果為static1,instance2。
11.請利用class重新定義Cat,並讓它從已有的Animal繼承,然後新增一個方法say(),
返回字串'Hello, xxx!'
class Animal {
constructor(name) {
this.name = name;
}
}
-
class Animal {
-
constructor(name) {
-
this.name = name;
-
}
-
}
-
class Cat extends Animal{
-
constructor(name){
-
super(name);
-
}
-
say(){
-
return 'hello xxxx!';
-
}
-
}
12.接上面程式分析下面程式碼執行結果為
var kitty = new Cat('Kitty');
var doraemon = new Cat('哆啦A夢');
if ((new Cat('x') instanceof Animal) && kitty && kitty.name === 'Kitty' && kitty.say &&
typeof kitty.say === 'function' && kitty.say() === 'Hello,Kitty!' &&
kitty.say === doraemon.say) {
console.log('測試通過!');
} else {
console.log('測試失敗!');
}
結果為測試失敗。
原因為kitty.say() === 'Hello,Kitty!'與say()方法的輸出不符應該為helloxxxx。
13.下面程式執行結果為
(typeof (new (class { class () {} })));
結果為objiect。在有new的時候都是一個例項物件。
2、node 和 java/php區別?
這三總語言最明顯的區別也是最基本的區別就是,Node.js 是一個基於 Chrome V8 引擎的 JavaScript 執行環境。而java和php是一個程式語言。
node相對於java而言相對於大專案java更容易管理不容易出錯。而node的優勢就是開發快,運算效率高,但是node運用的是js的開發語言,需要執行時才會知道哪裡出了問題,java不會他會及時的給予開發者錯誤反饋。
而node相對於php而言就是一下幾種區別:
1、效能方面:
由於 Node.js 遵循事件驅動的非阻塞I/O模型,與傳統的後端技術相比,Node.js 能夠處理大量的伺服器請求。PHP 遵循一個阻塞模型,其中在伺服器端建立多個執行緒來處理多個客戶端請求,如果程式碼沒有被優化,它會導致高伺服器負載和響應時間。
2、託管和部署:
PHP 應用程式可以在包括 Nginx 和 Apache 以及 Windows 和 Linux 平臺在內的任何伺服器上執行,這使得部署過程變得更容易。
而 Node.js,則需要具有 SSH 訪問許可權的虛擬伺服器。因此,在沒有任何控制檯命令和 Secure Shell(SSH)知識的情況下,用 PHP 部署小型企業和個人應用會更好。
3、外部依賴:
Node.js 依賴關係較少,用幾行程式碼就可以設定一個 Web 伺服器。但執行 PHP 應用程式,就需要外部伺服器軟體。用 Node.js 的開發人員只需要 NPM(節點包管理器)就可以下載 Node 模組,這些模組可以輕鬆地整合到應用程式中,提供額外的功能。
4、CPU 擴充套件任務:
Node.js 可能在高吞吐量方面表現優異,但是當應用程式繁重,需要 CPU 做大量工作時,Node.js 肯定會有所欠缺。在這種情況下,PHP 最適合做 Web 應用程式的後端。
5、單頁應用程式:
如果您使用過 Gmail,那麼您可能知道什麼是單頁應用程式(Single Page Application)。Web 應用程式在初始客戶端請求時載入,之後根據客戶端請求重新整理的網頁的特定部分。Node.js 與 AngularJS 的聯合是開發單頁應用程式的完美方案。
6、開發環境:
Node.js 可以用於桌面應用程式開發(Windows,Linux和Mac),移動應用程式開發(混合和跨平臺應用程式),甚至構建基於控制檯的應用程式。雖然有一些也可以使用 PHP 來開發,但是大多數開發人員不會這樣做。
7、社群支援:
由於 PHP 比 Node.js 早誕生將近20年,所以在文件,API 和程式碼庫等線上資源方面更為豐富。所以很有可能其他人也嘗試了你想要用程式碼完成的事情並從中獲得了幫助。
另一方面,Node.js 雖然已經得到了開發者和組織的廣泛關注,但是它支援開發者開發的資源缺相當少。
Node.js 和 PHP是相輔相成的,因為這兩種技術都有各自的優點和缺點。這大多是相似的情況在比較或選擇用於Web,桌面和移動開發的其他技術時。Node.js有前途,並且肯定會佔據PHP市場的一部分,但是不能完全取代 PHP。
同步和非同步區別?
同步:
所有的操作都做完,才返回給使用者。這樣使用者線上等待的時間太長,給使用者一種卡死了的感覺(就是系統遷移中,點選了遷移,介面就不動了,但是程式還在執行,卡死了的感覺)。這種情況下,使用者不能關閉介面,如果關閉了,即遷移程式就中斷了。
非同步:
將使用者請求放入訊息佇列,並反饋給使用者,系統遷移程式已經啟動,你可以關閉瀏覽器了。然後程式再慢慢地去寫入資料庫去。這就是非同步。但是使用者沒有卡死的感覺,會告訴你,你的請求系統已經響應了。你可以關閉介面了。
同步,是所有的操作都做完,才返回給使用者結果。即寫完資料庫之後,再響應使用者,使用者體驗不好。
非同步,不用等所有操作都做完,就相應使用者請求。即先響應使用者請求,然後慢慢去寫資料庫,使用者體驗較好。
非同步操作例子
為了避免短時間大量的資料庫操作,就使用快取機制,也就是訊息佇列。先將資料放入訊息佇列,然後再慢慢寫入資料庫。
引入訊息佇列機制,雖然可以保證使用者請求的快速響應,但是並沒有使得我資料遷移的時間變短(即80萬條資料寫入mysql需要1個小時,用了redis之後,還是需要1個小時,只是保證使用者的請求的快速響應。使用者輸入完http url請求之後,就可以把瀏覽器關閉了,幹別的去了。如果不用redis,瀏覽器不能關閉)。
同步就沒有任何價值了嗎?
比如網站的登入效果,銀行的轉賬等等都需要同步的操作。
判斷資料夾下檔案狀態
-
const fs=require('fs');
-
fs.readdir(__dirname,(err,files)=>{
-
if(err) throw err;
-
console.log(files);
-
for(let i=0;i<files.length;i++){
-
fs.stat(__dirname+'/'+files[i],(err,stats)=>{
-
if(stats.isFile()){
-
console.log(files[i]+'是一個檔案')
-
}else{
-
console.log(files[i]+'是一個檔案')
-
}
-
})
-
}
-
});
登入和註冊功能?登入使用get請求 註冊使用post請求 請求的路徑都是submit前端兩個頁面,後臺只有一個js檔案
html程式碼(get請求):
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta charset="utf-8">
-
<title></title>
-
</head>
-
<body>
-
<form class="mui-input-group" action="http://localhost:8989/submit/" method="get">
-
<div class="mui-input-row">
-
<label>註冊</label>
-
<input type="text" class="mui-input-clear" placeholder="使用者名稱" name="user">
-
<input type="password" class="mui-input-clear" placeholder="密碼" name="pass">
-
<input type="submit"/>
-
<a href="index2.html">登入</a>
-
</div>
-
</body>
-
</html>
html(post請求):
-
<html>
-
<head>
-
<meta charset="utf-8">
-
<title></title>
-
</head>
-
<body>
-
<form class="mui-input-group" action="http://localhost:8989/submit/" method="post">
-
<div class="mui-input-row">
-
<label>登入</label>
-
<input type="text" class="mui-input-clear" placeholder="使用者名稱" name="user">
-
<input type="password" class="mui-input-clear" placeholder="密碼" name="pass">
-
<input type="submit"/>
-
<a href="index.html">註冊</a>
-
</div>
-
</form>
-
</body>
-
</html>
js程式碼:
-
const http=require('http');
-
const fs=require('fs');
-
const path=require('path');
-
const readfile=require('readfile');
-
const url=require('url');
-
const querystring=require('querystring');
-
let server=http.createServer((req,res)=>{
-
if(req.url=='/favicon.ico') return;
-
if(req.url.startsWith('/form')){
-
readfile(__dirname,req,res);
-
}else if(req.url.startsWith('/submit')){
-
if(url.parse(req.url,true).query=={}){
-
let params=url.parse(req.url,true).query;
-
res.writeHead(200,{'Content-type':'text/plain;charset=utf-8'});
-
res.end(`使用者名稱${params.user}密碼是${params.pass}`);
-
}
-
else{
-
var allData='';
-
req.on('data',(chunk)=>{
-
allData+=chunk;
-
});
-
req.on('end',()=>{
-
console.log(querystring.parse(allData));
-
let a=querystring.parse(allData);
-
res.writeHead(200,{'Content-type':'text/plain;charset=utf-8'});
-
res.end(`使用者名稱${a.user}密碼是${a.pass}`);
-
});
-
}
-
}else{
-
res.end('404');
-
}
-
});
-
server.listen('8989');
使用express來實現上述程式碼
html(get):
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta charset="utf-8">
-
<title></title>
-
<script src="../../public/js/jquery-3.0.0.min.js"></script>
-
</head>
-
<body>
-
<h1>登入頁面</h1>
-
<input type="text" placeholder="使用者名稱" name="uesr" />
-
<span></span>
-
<br><br>
-
<input type="password" placeholder="密碼" name="pass" />
-
<button type="button">登入</button>
-
<a href="index2.html">註冊賬號</a>
-
</body>
-
<script>
-
$('button').click(()=>{
-
$.ajax({
-
url:'http://localhost:8989/submit',
-
method:'get',
-
data:{
-
user:$('input[type="text"]').val(),
-
pass:$('input[type="password"]').val()
-
},
-
success:function(res){
-
if(res=='lp'){
-
$('span').html('該使用者名稱存在請重新輸入');
-
}else{
-
$('span').html('√');
-
location.href='app.html';
-
}
-
}
-
})
-
})
-
</script>
-
</html>
html(post):
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta charset="utf-8">
-
<title></title>
-
<script type="text/javascript" src="../../public/js/jquery-3.0.0.min.js"></script>
-
</head>
-
<body>
-
<h1>註冊頁面</h1>
-
<input type="text" placeholder="使用者名稱" name="uesr" />
-
<span></span>
-
<br><br>
-
<input type="password" placeholder="密碼" name="pass" />
-
<button type="button">註冊</button>
-
<a href="index2.html">登入賬號</a>
-
</body>
-
<script>
-
$('button').click(()=>{
-
$.ajax({
-
method:'post',
-
url:'http:localhost:8989/submit',
-
data:{
-
user:$('input[type="text"]').val(),
-
pass:$('input[type="password"]').val()
-
},
-
success:(res)=>{
-
if(res=='lp'){
-
$('span').html('該使用者名稱存在請重新輸入');
-
}else{
-
$('span').html('√');
-
location.href='app.html';
-
}
-
}
-
})
-
})
-
</script>
-
</html>
express模組程式碼:
-
const express=require('express');
-
const app=express();
-
var bodyParser=require('body-parser');
-
var urlencodedParser=bodyParser.urlencoded({extended:false});
-
app.use('/',express.static('./www/form'));
-
app.use('/public',express.static('./public'));
-
app.post('/submit',urlencodedParser,(req,res)=>{
-
res.send(req.body);
-
});
-
app.get('/submit',(req,res)=>{
-
res.send(`${req.query.user}`)
-
});
-
app.listen('8989');
關係型資料庫有哪些,非關係型資料庫有哪些?兩者區別?
1、資料儲存方式不同。
關係型和非關係型資料庫的主要差異是資料儲存的方式。關係型資料天然就是表格式的bai,因此儲存在資料表的行和列中。資料表可以彼此關聯協作儲存,也很容易提取資料。
與其相反,非關係型資料不適合儲存在資料表的行和列中,而是大塊組合在一起。非關係型資料通常儲存在資料集中,就像文件、鍵值對或者圖結構。你的資料及其特性是選擇資料儲存和提取方式的首要影響因素。
2、擴充套件方式不同。
SQL和NoSQL資料庫最大的差別可能是在擴充套件方式上,要支援日益增長的需求當然要擴充套件。
要支援更多併發量,SQL資料庫是縱向擴充套件,也就是說提高處理能力,使用速度更快速的計算機,這樣處理相同的資料集就更快了。
因為資料儲存在關係表中,操作的效能瓶頸可能涉及很多個表,這都需要通過提高計算機效能來客服。雖然SQL資料庫有很大擴充套件空間,但最終肯定會達到縱向擴充套件的上限。而NoSQL資料庫是橫向擴充套件的。
而非關係型資料儲存天然就是分散式的,NoSQL資料庫的擴充套件可以通過給資源池新增更多普通的資料庫伺服器(節點)來分擔負載。
3、對事務性的支援不同。
如果資料操作需要高事務性或者複雜資料查詢需要控制執行計劃,那麼傳統的SQL資料庫從效能和穩定性方面考慮是你的最佳選擇。SQL資料庫支援對事務原子性細粒度控制,並且易於回滾事務。
雖然NoSQL資料庫也可以使用事務操作,但穩定性方面沒法和關係型資料庫比較,所以它們真正閃亮的價值是在操作的擴充套件性和大資料量處理方面。
資料庫操作方法
建立(使用)資料庫:
我們建立了資料庫 runoob:
-
> use runoob
-
switched to db runoob
-
> db
-
runoob
刪除資料庫
首先,檢視所有資料庫:
-
> show dbs
-
admin 0.000GB
-
config 0.000GB
-
local 0.000GB
-
runoob 0.000GB
接下來我們切換到資料庫 runoob:
-
> use runoob
-
switched to db runoob
-
>
執行刪除命令:
-
> db.dropDatabase()
-
{ "dropped" : "runoob", "ok" : 1 }
最後,我們再通過 show dbs 命令資料庫是否刪除成功:
-
> show dbs
-
admin 0.000GB
-
config 0.000GB
-
local 0.000GB
刪除集合
集合刪除語法格式如下:
db.collection.drop()
以下例項刪除了 runoob 資料庫中的集合 site:
-
> use runoob
-
switched to db runoob
-
> db.createCollection("runoob") # 先建立集合,類似資料庫中的表
-
> show tables # show collections 命令會更加準確點
-
runoob
-
> db.runoob.drop()
-
true
-
> show tables
-
>
更新文件
-
db.collection.update(
-
<query>,
-
<update>,
-
{
-
upsert: <boolean>,
-
multi: <boolean>,
-
writeConcern: <document>
-
}
-
)
引數說明:
- query: update的查詢條件,類似sql update查詢內where後面的。
- update: update的物件和一些更新的操作符(如$,$inc...)等,也可以理解為sql update查詢內set後面的
- upsert: 可選,這個引數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,預設是false,不插入。
- multi: 可選,mongodb 預設是false,只更新找到的第一條記錄,如果這個引數為true,就把按條件查出來多條記錄全部更新。
- writeConcern:可選,丟擲異常的級別。
只更新第一條記錄:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
只新增第一條:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
全部新增進去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
只更新第一條記錄:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );
查詢文件
db.collection.find(query, projection)
- query:可選,使用查詢操作符指定查詢條件
- projection:可選,使用投影操作符指定返回的鍵。查詢時返回文件中所有鍵值, 只需省略該引數即可(預設省略)。
例項
以下例項我們查詢了集合 col 中的資料:
-
> db.col.find().pretty()
-
{
-
"_id" : ObjectId("56063f17ade2f21f36b03133"),
-
"title" : "MongoDB 教程",
-
"description" : "MongoDB 是一個 Nosql 資料庫",
-
"by" : "菜鳥教程",
-
"url" : "http://www.runoob.com",
-
"tags" : [
-
"mongodb",
-
"database",
-
"NoSQL"
-
],
-
"likes" : 100
-
}
實現商品增刪改查的功能
其實具體的方法很簡單只是把得到的資料放入html進行展示,只是有的時候會有些東西容易被忽略。
-
const express=require('express');
-
const app=express();
-
const dao=require('./model/dao.js');
-
app.use('/',express.static('./www/form'));
-
app.use('/public',express.static('./public/'));
-
app.get('/add',(req,res)=>{
-
var obj={
-
proname:req.query.proname,
-
proprice:req.query.proprice
-
}
-
dao.insert('product','phone',obj,function(r){
-
res.send(r);
-
})
-
})
-
app.get('/del',(req,res)=>{
-
var obj={
-
proname:req.query.proname
-
}
-
dao.delete('product','phone',obj,(r)=>{
-
res.send(r);
-
})
-
})
-
app.get('/find',(req,res)=>{
-
dao.find('product','phone',(r)=>{
-
res.send(r)
-
},{},{},0,10)
-
})
-
app.get('/update',(req,res)=>{
-
var obj={
-
proname:req.query.proname,
-
proprice:req.query.proprice
-
}
-
var updateStr={
-
uponame:req.query.uponame,
-
upoprice:req.query.upoprice
-
}
-
dao.update('product','phone',obj,updateStr,function(r){
-
res.send(r);
-
})
-
})
-
app.listen('8989');
增刪改查的封裝
-
// 引入資料庫包,可以在php中操作資料庫
-
const MongoClient=require('mongodb').MongoClient;
-
// 資料庫地址
-
const url="mongodb://localhost:27017";
-
// 把資料庫連線的操作,封裝起來。
-
function _connect(callback){
-
// 連線上資料庫
-
//連線資料庫是非同步操作,不知道什麼時候連線成功了。用到回撥函式的概念
-
MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
-
// 連線資料庫成功
-
if (err) throw err;
-
// 說明連線資料庫成功了 db代表連線成功以後返回的資料
-
callback(db);
-
});
-
}
-
// module.exports匯出資料
-
module.exports.insert=function(dbname,col,myobj,callback){
-
_connect(function(db){
-
// db連線成功的資料
-
// db.db('操作的資料庫')
-
var dbo = db.db(dbname);
-
// 插入的資料
-
// var myobj = { name: "菜鳥教程", url: "www.runoob" };
-
// 選擇的資料庫.collection('集合班級').insertOne(資料,(err,r)=>{
-
// 資料插入成功
-
// })
-
// 一條資料是物件 insertOne 多條資料是陣列 用insertmMany
-
if(myobj instanceof Array){
-
myobj=myobj
-
}else{
-
myobj=[myobj]
-
}
-
dbo.collection(col).insertMany(myobj, function(err,r) {
-
if (err) throw err;
-
db.close();
-
// r得到的是成功插入資料的資訊
-
callback(r)
-
})
-
})
-
}
-
// 查詢封裝的時候,考慮是否需要分頁是否需要排序
-
// 需要書寫函式引數的預設值,因為使用者有可能不會書寫
-
module.exports.find=function(dbname,col,callback,myobj={},mysort={},myskip=0,mylimit=0){
-
_connect(function(db){
-
// 查詢資料
-
var dbo = db.db(dbname);
-
// sort排序
-
// skip跳過多少條資料
-
// limit()限制取資料的數量
-
dbo.collection(col).find(myobj).sort(mysort).skip(myskip).limit(mylimit).toArray(function(err, result) { // 返回集合中所有資料
-
if (err) throw err;
-
console.log(result);
-
db.close();
-
callback(result);
-
})
-
})
-
}
-
module.exports.update=function(dbname,col,myobj,updateObj,callback){
-
_connect(function(db){
-
var dbo = db.db(dbname);
-
var updateStr = {$set: updateObj};
-
// updateOne(查詢條件,更改的資料)
-
dbo.collection(col).updateOne(myobj, updateStr, function(err, res) {
-
if (err) throw err;
-
console.log("文件更新成功");
-
db.close();
-
callback(res)
-
});
-
})
-
}
-
module.exports.delete=function(dbname,col,myobj,callback){
-
_connect(function(db){
-
var dbo = db.db(dbname);
-
// updateOne(查詢條件,更改的資料)
-
dbo.collection(col).deleteOne(myobj, function(err,obj) {
-
if (err) throw err;
-
db.close();
-
callback(obj);
-
});
-
})