Skip to content

Commit

Permalink
feet: 编程题增加分类
Browse files Browse the repository at this point in the history
  • Loading branch information
funnycoderstar committed Apr 30, 2022
1 parent b3260bb commit 961b6ea
Show file tree
Hide file tree
Showing 13 changed files with 1,055 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ _book/
.DS_Store
./docs/.vuepress/dist
/dist/
/temp/
73 changes: 45 additions & 28 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,29 +166,46 @@ module.exports = {
},
],
'/jsCode/': [
['/jsCode/', '手写代码系列'],
['/jsCode/防抖', '手写一个防抖'],
['/jsCode/节流', '手写一个节流'],
['/jsCode/浅比较和深比较', '浅比较和深比较'],
['/jsCode/浅拷贝和深拷贝', '浅拷贝和深拷贝'],
['/jsCode/数组乱序', '数组乱序'],
['/jsCode/函数柯里化', '函数柯里化'],
['/jsCode/实现一个Promise', '实现一个Promise'],
['/jsCode/实现一个new', '实现一个new'],
['/jsCode/实现instanceof', '实现instanceof'],
['/jsCode/实现flat', '实现flat'],
['/jsCode/手写继承', '手写继承'],
['/jsCode/实现一个async函数', '实现一个async函数'],
['/jsCode/实现一个iterator', '实现一个iterator'],
['/jsCode/setTimeout实现setInterval', 'setTimeout实现setInterval'],
['/jsCode/限制并发请求', '限制并发请求'],
['/jsCode/实现一个repeat方法', '实现一个repeat方法'],
['/jsCode/简单实现一个Vue的双向绑定', '简单实现一个Vue的双向绑定'],
['/jsCode/实现一个vue自定义指令-懒加载', '实现一个vue自定义指令-懒加载'],
['/jsCode/实现一个轮播图', '实现一个轮播图'],
['/jsCode/放大镜效果', '放大镜效果'],
['/jsCode/LazyMan', '实现一个LazyMan'],
['/jsCode/发布-订阅模式的实现', '发布-订阅模式的实现'],
{
title: 'API 实现',
collapsable: true,
children: [
['/jsCode/实现一个Promise', '实现一个Promise'],
['/jsCode/实现一个new', '实现一个new'],
['/jsCode/实现instanceof', '实现instanceof'],
['/jsCode/实现flat', '实现flat'],
['/jsCode/手写继承', '手写继承'],
['/jsCode/实现一个async函数', '实现一个async函数'],
['/jsCode/实现一个iterator', '实现一个iterator'],
['/jsCode/setTimeout实现setInterval', 'setTimeout实现setInterval'],
['/jsCode/发布-订阅模式的实现', '实现一个 EventEmitter'],
],
title: '功能函数实现',
collapsable: true,
children: [
['/jsCode/防抖', '手写一个防抖'],
['/jsCode/节流', '手写一个节流'],
['/jsCode/浅比较和深比较', '浅比较和深比较'],
['/jsCode/浅拷贝和深拷贝', '浅拷贝和深拷贝'],
['/jsCode/数组乱序', '数组乱序'],
['/jsCode/函数柯里化', '函数柯里化'],
],
title: 'Promise 异步相关',
collapsable: true,
children: [
['/jsCode/限制并发请求', '限制并发请求'],
['/jsCode/实现一个repeat方法', '实现一个repeat方法'],
['/jsCode/LazyMan', '实现一个LazyMan'],
],
title: '功能实现',
collapsable: true,
children: [
['/jsCode/简单实现一个Vue的双向绑定', '简单实现一个Vue的双向绑定'],
['/jsCode/实现一个vue自定义指令-懒加载', '实现一个vue自定义指令-懒加载'],
['/jsCode/实现一个轮播图', '实现一个轮播图'],
['/jsCode/放大镜效果', '放大镜效果'],
],
},
],
'/interview/': [
['/interview/', '前端相关'],
Expand Down Expand Up @@ -255,7 +272,7 @@ module.exports = {
],
},
{
title: '笔试题',
title: '代码输出题',
collapsable: true,
children: [
// ['/interview/笔试题/1', '笔试题1'],
Expand All @@ -264,10 +281,10 @@ module.exports = {
// ['/interview/笔试题/4', '笔试题4'],
// ['/interview/笔试题/5', '笔试题5'],
// ['/interview/笔试题/6', '笔试题6'],
['/interview/笔试题/3', '笔试题1'],
['/interview/笔试题/4', '笔试题2'],
['/interview/笔试题/5', '笔试题3'],
['/interview/笔试题/6', '笔试题4'],
['/interview/笔试题/3', '代码输出题1'],
['/interview/笔试题/4', '代码输出题2'],
['/interview/笔试题/5', '代码输出题3'],
['/interview/笔试题/6', '代码输出题4'],
],
},
// {
Expand Down
Empty file.
30 changes: 17 additions & 13 deletions docs/algorithm/数学/计算质数.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,38 @@

## 解题思路

质数:指在大于1的自然数中,除了1和它本身不再有其他因数的自然数。质数又称素数。
质数:指在大于 1 的自然数中,除了 1 和它本身不再有其他因数的自然数。质数又称素数。

### 厄拉多塞筛法
先将2-n的个数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数,第一个既未画圈又没有划去的数是3,将它画圈,再划去3的其他倍数;
现在即未画圈又没有划去的数是5,将它画圈并划去5的其他倍数......依次类推,一直到所有小于或等于N的各数都画了圈或者划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于N的素数。

先将 2-n 的个数放入表中,然后在 2 的上面画一个圆圈,然后划去 2 的其他倍数,第一个既未画圈又没有划去的数是 3,将它画圈,再划去 3 的其他倍数;
现在即未画圈又没有划去的数是 5,将它画圈并划去 5 的其他倍数......依次类推,一直到所有小于或等于 N 的各数都画了圈或者划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 N 的素数。

![img](https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1589090399702.gif)

每计算一个数,都要把它的倍数去掉。到了n,数一下留下了几个数。
每计算一个数,都要把它的倍数去掉。到了 n,数一下留下了几个数。

## 解题方法

```js
/**
* @param {number} n
* @return {number}
*/
var countPrimes = function(n) {
let count = 0;
signs = new Array(n + 1);
for(let i = 2; i < n; i++) {
if(!signs[i]) {
count++;
for(let j = 2 * i; j < n; j+=i) {
signs[j] = true;
// isPrime[i] 表示数 i 是不是质数,如果是质数则为 1,否则为 0
let isPrimes = new Array(n).fill(1);
let ans = 0;
for (let i = 2; i < n; i++) {
if (isPrimes[i]) {
ans += 1;
// 从小到大遍历每个数,如果这个数为质数,则将其所有的倍数都标记为合数(除了该质数本身)即 00
// 这样在运行结束的时候我们即能知道质数的个数。
for (let j = i * i; j < n; j += i) {
isPrimes[j] = 0;
}
}
}
return count;
return ans;
};
```
```
28 changes: 28 additions & 0 deletions docs/algorithm/数组/区域和检索 - 数组不可变.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
303. 区域和检索 - 数组不可变

使用前缀和,提高检索速度,时间复杂度为 O(1).

```js
/**
* @param {number[]} nums
*/
var NumArray = function(nums) {
let n = nums.length;
this.sums = new Array(n + 1).fill(0);
for (let i = 0; i < n; i++) {
// sums[i]表示 nums 从下标 00 到下标 i-1i−1 的前缀和。
this.sums[i + 1] = nums[i] + this.sums[i];
}
};

/**
* @param {number} left
* @param {number} right
* @return {number}
*/
NumArray.prototype.sumRange = function(left, right) {
return this.sums[right + 1] - this.sums[left];
};
```

前缀和主要适用的场景是原始数组不会被修改的情况下,频繁查询某个区间的累加和。
3 changes: 3 additions & 0 deletions docs/algorithm/树/501.二叉搜索树中的众数.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 思路

二叉搜索树,中序遍历是升序的。重复的数字一定是连续的,可以转变为,求有序数组中的众数。
12 changes: 6 additions & 6 deletions docs/jsCode/LazyMan.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

```js
实现一个LazyMan,可以按照以下方式调用:
LazyMan(Hank)输出:
LazyMan("Hank")输出:
Hi! This is Hank!

LazyMan(Hank).sleep(10).eat(dinner”)输出
LazyMan("Hank").sleep(10).eat("dinner") 输出
Hi! This is Hank!
//等待10秒..
Wake up after 10
Eat dinner~

LazyMan(Hank).eat(dinner).eat(supper”)输出
LazyMan('Hank').eat('dinner').eat('supper') 输出
Hi This is Hank!
Eat dinner~
Eat supper~

LazyMan(Hank).sleepFirst(5).eat(supper)输出
LazyMan("Hank").sleepFirst(5).eat("supper")输出
//等待5秒
Wake up after 5
Hi This is Hank!
Expand Down Expand Up @@ -51,7 +51,7 @@ class LazyMan {
while (Date.now() - time < delay) {}
// 为什么在setTimeout里返回this不行, 函数执行会先于setTimeout里面的函数执行
setTimeout(() => {
console.log(' sleep wake up after ' + ms);
console.log('sleep wake up after ' + ms);
}, 0);

return this;
Expand Down Expand Up @@ -133,7 +133,7 @@ class _LazyMan {
});
return this.next();
}
beforSleep(time) {
beforeSleep(time) {
// unshift插入到事件的第一个
this.taskQueue.unshift(() => this.sleepPromise(time));
return this.next();
Expand Down
59 changes: 40 additions & 19 deletions docs/jsCode/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
### 目录
- [实现一个防抖](./防抖.md)
- [手写一个节流](./节流.md)
- [浅比较和深比较](./浅比较和深比较.md)
- [浅拷贝和深拷贝](./浅拷贝和深拷贝.md)
- [数组乱序](./数组乱序.md)
- [函数柯里化](./函数柯里化.md)
- [实现一个Promise](./实现一个Promise.md)
- [实现一个new](./实现一个new.md)
- [实现instanceof](./实现instanceof.md)
- [手写继承](./手写继承.md)
- [实现一个async函数](./实现一个async函数.md)
- [实现一个iterator](./实现一个iterator.md)
- [setTimeout实现setInterval](./setTimeout实现setInterval.md)
- [限制并发请求](./限制并发请求.md)
- [简单实现一个Vue的双向绑定](./简单实现一个Vue的双向绑定.md)
- [实现一个vue自定义指令-懒加载](./实现一个vue自定义指令-懒加载.md)
- [实现一个轮播图](./实现一个轮播图.md)
- [实现一个放大镜效果](./放大镜效果.md)
## 目录

通过题目来学习一些 javaScript 基础知识

### API 实现

- [实现一个 new](./实现一个new.md)
- [实现 instanceof](./实现instanceof.md)
- [实现一个 iterator](./实现一个iterator.md)
- [setTimeout 实现 setInterval](./setTimeout实现setInterval.md)
- [写 call,apply,bind](./手写call,apply,bind.md)
- [实现一个 EventEmitter](./发布-订阅模式的实现.md)

### 功能函数实现

- [手写继承](./手写继承.md)
- [实现一个防抖](./防抖.md)
- [手写一个节流](./节流.md)
- [浅比较和深比较](./浅比较和深比较.md)
- [浅拷贝和深拷贝](./浅拷贝和深拷贝.md)
- [数组乱序](./数组乱序.md)
- [函数柯里化](./函数柯里化.md)

### 数据结构转换

### Promise 异步相关

- [实现一个 Promise](./实现一个Promise.md)
- [实现一个 async 函数](./实现一个async函数.md)
- [限制并发请求](./限制并发请求.md)
- [实现一个 LazyMan](./LazyMan.md)
- [koa 洋葱模型 compose](./洋葱模型compose)
- [实现一个 repeat 方法](./实现一个repeat方法.md)

### 功能实现

- [简单实现一个 Vue 的双向绑定](./简单实现一个Vue的双向绑定.md)
- [实现一个 vue 自定义指令-懒加载](./实现一个vue自定义指令-懒加载.md)
- [实现一个轮播图](./实现一个轮播图.md)
- [实现一个放大镜效果](./放大镜效果.md)
3 changes: 3 additions & 0 deletions docs/jsCode/compose和pipe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 参考

- [compose 函数和 pipe 函数](http://dennisgo.cn/Articles/JavaScript/ComposePipe.html)
Empty file.
Empty file.
30 changes: 30 additions & 0 deletions docs/jsCode/洋葱模型compose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## koa 的洋葱模型

```js
app.use((next) => {
console.log(1);
next();
console.log(4);
});
app.use((next) => {
console.log(2);
next();
console.log(5);
});
app.use((next) => {
console.log(3);
next();
console.log(6);
});
app.compose();
// 输出是123654;
```

当程序运行到 next()的时候就会暂停当前程序,进入下一个中间件,处理完之后才会回过头来继续处理。

核心:中间件管理和 next 实现,其中 next 是巧妙的使用了 Promise 特性。洋葱模型,本质上是 Promise.resolve()的递归。

## 参考

- [Koa 洋葱模型原理分析](https://lq782655835.github.io/blogs/node/koa-compose-modal.html)
- [Koa2 洋葱模型 —— compose 串联中间件的四种实现](https://segmentfault.com/a/1190000016707187)
Loading

0 comments on commit 961b6ea

Please sign in to comment.