├── connect.jpg ├── xyq.md ├── .gitignore ├── LICENSE ├── README.md └── q.md /connect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/ama/HEAD/connect.jpg -------------------------------------------------------------------------------- /xyq.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1) 4 | 5 | - 走步,九圈,一圈二三十步 6 | - 站桩二十分分钟,坐跨 7 | 8 | 2) 9 | 10 | - 三个开肩小动作:指天画地、展翅、风摆荷叶 11 | - 走步 12 | - 站桩,30分钟 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 他们叫我狼叔 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 《Node全栈》 2 | 3 | ## 做Node全栈,你合格么? 4 | 5 | 自测一下 6 | 7 | - 大前端相关 8 | - 基础 9 | - css 2 && 3 10 | - js && es6 11 | - http/ajax/rest 12 | - git/svn/issues/pr 13 | - markdown 14 | - 前端框架 15 | - 模块化加载seajs\requirejs\commonjs 16 | - mvc/mvvm 17 | - Bootstrap 18 | - jQuery/Extjs/Dojo/Mootools/Yui 19 | - Backbone 20 | - Angular 21 | - 移动端 22 | - h5/localstorage/websocket/canvas 23 | - phonegap/cordova 24 | - 是否具备编写原生插件能力 25 | - 优化:fastclick,zepto,iscroll等 26 | - 框架:sencha、jqmobile、ionicframework等 27 | - 最新技术 28 | - react 全家桶 29 | - vue2 全家桶 30 | - angular 2/ionic 2 31 | - react-native/weex 32 | - electron/nw.js 33 | - 个人成长与技能 34 | - 通过开源项目学习 35 | - Git和GitHub 36 | - VSCode与Node调试 37 | - 个人成长 38 | - 有观点的八卦 39 | - 数据结构与设计模式 40 | - Node 41 | - Node是什么 42 | - Node新手入门 43 | - 异步流程控制 44 | - 如何编写和发布npm模块 45 | - 10分钟写脚手架 46 | - cli工具举例 47 | - 变态npm 48 | - Stream 49 | - Node考证 50 | - 跨平台 51 | - Node Web框架 52 | - 测试 53 | - bdd/tdd 54 | - qunit 55 | - mocha/jest/ava/tap/jasmine + karma 56 | - cucumber 57 | - spies, stubs and mocks 58 | - faker/sinon 59 | - chai/should 60 | - jenkins/travis 61 | - 工程化 62 | - precommit 63 | - 环境变量与开发部署 64 | - 自己动手写一个web框架 65 | - 阿里云部署node 66 | - Node部署 67 | - 日志采集问题 68 | - 前端三大框架 69 | - webpack 70 | - 学习预编译 71 | - Typescrpt 72 | - tpl和vue的异同 73 | - Livereload 74 | - 代理:多环境下提高开发效率 75 | - Bigpipe 76 | - 优化移动端加载速度 77 | - 你可以做的更多 78 | - 页面即服务 79 | - 使用node编写微服务 80 | - Node源码阅读与调试 81 | - 运维 82 | - 内存与性能 83 | - redis科普 84 | - mongodb和mongoose 85 | - addon开发和应对cpu密集任务 86 | - Api模拟与管理 87 | - 高效工具 88 | - coffee/typescript 89 | - sass/less/stylus 90 | - postcss/uncss 91 | - yeoman/slush 92 | - npm/bower/component 93 | - gulp/grunt/webpack 94 | - browserfy 95 | - hexo/jekyll 96 | - 工具类 97 | - 编辑器 98 | - 调试工具 99 | - 调优工具 100 | - 案例讨论:如何设计一个高并发的活动系统 101 | - 其他 102 | - linux/shell 103 | - 语言node、java、.net、php、python、perl等 104 | - rdbms/nosql 105 | - 读过哪些经典的前端相关书? 106 | - 如何参与开源项目 107 | 108 | 你合格么? 109 | 110 | ## Node是什么 111 | 112 | - 怎么运行 113 | - ee 114 | - 单线程,不脆弱 115 | - c++(libuv和eventloop) 116 | - py 117 | - js和c++如何互通 118 | - 写法与约定 119 | - commonjs和实现 120 | - error-first cb 121 | - eventemiter 122 | - 编码风格 123 | 124 | ## Node新手入门 125 | 126 | - 如何学习 127 | - node安装 128 | - 3m大法+nvs 129 | - 为什么需要py 130 | - 开发限制 131 | - 推荐的书 132 | - 基本技能 133 | - 参见《写开源项目》一章 134 | 135 | ## 通过开源项目学习 136 | 137 | - 迷茫时学习Node.js最好的方法:每日精进,每天学10个npm 138 | - 如何学 139 | - 前端构建等等 140 | - Study-For-StuQ 141 | 142 | ## Git和GitHub 143 | 144 | git 145 | 146 | - 和svn对比 147 | - 无server 148 | - 分布式 149 | - 分支 150 | - git工作流模型 151 | - 开发和提pr流程 152 | - cherrypick 153 | - gitlab 154 | - githook 155 | - pr 156 | 157 | github 158 | 159 | - ghpages 160 | - 博客 161 | - gitbook 162 | - md和编译 163 | - tocmd做法 164 | 165 | ## VSCode与Node调试 166 | 167 | - vscode用法和快捷键 168 | - 对比各种编辑器 169 | - 各种调试 170 | - 单个文件调试 171 | - 固定文件调试 172 | - 跨进程调试 173 | - 远程调试 174 | - debug和inspect协议 175 | - npm xx 176 | - githook 177 | - 单元测试插件 178 | - 自己写一个vscode插件 179 | 180 | ## 异步流程控制 181 | 182 | - 学习要点:promise和async函数 183 | - promise并行如何写:all和race,比如获取多个接口的数据 184 | - sleep写法 185 | - async函数和async.js不是一个东西 186 | - 异常处理 187 | 188 | ## 如何编写和发布npm模块 189 | 190 | - 创建git项目 191 | - 写点代码 192 | - 发布 193 | - better 发布 194 | - 搭建私有源 195 | - 解释registry的关系 196 | 197 | ## 10分钟写脚手架 198 | 199 | 1. 初始化模块 200 | 1. cli二进制模块 201 | 1. 模板引擎使用 202 | 1. 解析cli参数和路径 203 | 1. npm发布 204 | 205 | ## cli工具举例 206 | 207 | - 入门见《10分钟写脚手架》 208 | - kp 209 | - je 210 | 211 | ## precommit 212 | 213 | - husky 214 | - standardjs 215 | - precommit = standard * && npm test 216 | - 测试,见test部分 217 | 218 | ## test 219 | 220 | - tdd/bdd 221 | - 模块 222 | - mocha、ava、jest、tape 223 | - chai 224 | - sinon 三个概念(spies,stub、mock) 225 | - supertest以及superagent原理 226 | - zombie 227 | - 例子 228 | - mocha、express和supertest做接口测试 229 | - ava、koa和supertest做接口测试 230 | - fixture概念 231 | - badge 232 | - travis(多版本自动化)和jenkins 233 | - 测试覆盖率 234 | - 其他 235 | - factory—girl 236 | - faker 237 | - Mock.js随机生成数据 238 | 239 | ## 变态npm 240 | 241 | - 黑洞 242 | - 生态 243 | - left-pad事件 244 | - shell写npm模块(适合运维和其他语言爱好者) 245 | - 配置(见precommit) 246 | - npm run xx 247 | - -D和-S区别 248 | - yarn 249 | 250 | ## 环境变量与开发部署 251 | 252 | - debug 253 | - NODE_ENV 254 | - dev 255 | - test 256 | - staging 257 | - product 258 | - webpack的配置 259 | 260 | ## Stream 261 | 262 | - pipe 263 | - http 264 | - gulp 265 | - request.end 266 | - ee 267 | 268 | ## 数据结构与设计模式 269 | 270 | - 基本array 271 | - LRU 272 | - trie 273 | - radix-tree 274 | 275 | 各种设计模式举几个例 276 | 277 | ## Node web框架 278 | 279 | - koa与express 280 | - 中间件 281 | - 路由(自动挂载路由) 282 | - 视图 283 | - 健壮性 284 | - koa-compose 285 | 286 | ## 自己动手写一个web框架 287 | 288 | - express/koa 289 | - thinkjs 290 | - slet 291 | 292 | ## 阿里云部署node 293 | 294 | - 买 295 | - 域名 296 | - 访问 297 | - 准备 298 | - cd 299 | 300 | ## Node部署 301 | 302 | - 为什么Node单线程单进程并不脆弱? 303 | - 4种启动方式 304 | - node 305 | - nodemon 306 | - forever 307 | - pm2 308 | - pm2用法 309 | - 基础管理、启动、查看状态、日志、监控等 310 | - 远程部署多台机器(如果复杂的,推荐使用saltstack,后面有专门的部署章节) 311 | - 部署模式思考 312 | - 8核8g的机器怎么部署 313 | - 1核1g 314 | - 防止雪崩 315 | - 部署实例和cpu核数的关系 316 | - 为什么4核上部署12个应用,cpu使用率会非常高 317 | 318 | ## 日志采集问题 319 | 320 | - elk、splank 321 | - sentry 322 | - h5=》采集=》grafana =》d3可时候会 323 | - 收集信息,mq,然后入库 324 | 325 | ## 页面即服务 326 | 327 | - 好处,对比单体应用 328 | - 成本优势,比如实习生能否搞定 329 | - 具体做法 330 | 331 | ## 使用node编写微服务 332 | 333 | - rpc 334 | - dnode 335 | - senaca 336 | - grpc 337 | - tcp(粘包)配置同步 338 | - global 339 | 340 | ## Node源码阅读与调试 341 | 342 | - clion 343 | - 调试 344 | 345 | ## 运维 346 | 347 | - 简单的纯node多机器pm2 348 | - 复杂的saltstack 349 | - devops 350 | 351 | ## 内存与性能 352 | 353 | - benchmark和压测 354 | - 4个工具 355 | - v8-profiler 对v8堆内存抓取快照和对cpu进行分析 356 | - node-heapdump 对v8堆内存抓取快照,事后分析+chrome分析 357 | - node-mtrace 分析堆栈使用 358 | - node-memwatch 监听垃圾回收情况 359 | - tracegc和prof+压测 360 | - 简易实现easy-monitor 361 | - 终极方案dtrace调优、火焰图 362 | - 偷懒做法:apm比如alinode、听云等 363 | 364 | ## redis科普 365 | 366 | - 五中数据结构 367 | - 读写分离 368 | - node选型:ioredis和源码 369 | - 美图弹幕系统分析 370 | - 做队列 371 | - pubsub 372 | - 存session 373 | - 限流 374 | 375 | ## mongodb和mongoose 376 | 377 | 不需要运维就可以有很好的性能 378 | 379 | - 事务 380 | - 启动mh 381 | - mr 382 | - expire 383 | - 部署 384 | - 副本集 385 | - sharding 386 | 387 | mongoose 388 | 389 | - mvc中m作用 390 | - 各种技巧 391 | 392 | ## 案例讨论:如何设计一个高并发的活动系统 393 | 394 | - 流程 395 | - 生成html(解析psd,坐标和图层) 396 | - mq、cache 397 | - 计算机器和限流量 398 | - 配置中心tcp 399 | - 限流 400 | - redis 401 | - global 402 | - incr与blpop 403 | - 中间件写法 404 | 405 | ## 你可以做的更多 406 | 407 | - sql的故事 408 | - psd转html 409 | - node做运维 410 | - shipit 411 | - gulp 412 | - npm #! /bin/bash 413 | - gulp-ftp 414 | - 静态化:写-》压缩-》cdn-》一键发布 415 | - 爬虫 416 | - 区块链:ipfs举例 417 | - 通过http和rpc等解耦 418 | - kafka提供http,美图的弹幕 419 | - rabbitmq 420 | - node-redis-java 421 | 422 | ## addon开发和应对cpu密集任务 423 | 424 | - nan 425 | - n-api 426 | - node-java 427 | - rust 428 | - napajs 429 | 430 | ## 前端三大框架 431 | 432 | - 点评前端三大框架 433 | - 基础、样例 434 | - 和node关系 435 | - 使用node做api后端 436 | - 学习构建和定制过程 437 | - 参见(通过开源项目学习) 438 | 439 | ## webpack 440 | 441 | - 模块化,按需加载 442 | - 模块,加载器和打包器 443 | - 打包过程 444 | - 浏览器加载过程 445 | - code spit 446 | - 通过react动态路由来分泡 447 | - tree shaking 448 | - 合并公共项目(react + react-router + redux 打成一个包) 449 | 450 | ## 学习预编译 451 | 452 | - 单个文件编译 453 | - 静态网站高级写法:moddileman类似的写法 454 | - 模板的好处 455 | - 10行代码写一个 456 | - express里的conect-xxx的中间件 457 | - ykit做法 458 | - gulp做法 459 | - webpack做法 460 | 461 | ## Typescrpt 462 | 463 | - js需要类型系统 464 | - 各种写法继承 465 | - ts-check 466 | - typeorm 467 | - 注解 468 | - 字节写一个web框架 469 | 470 | ## tpl和vue的异同 471 | 472 | - 直接写html很好,但太low了 473 | - tpl 474 | - vue 475 | - 布局等实现 476 | - 脚手架:基于tpl和vue的crud 477 | - ssr 478 | 479 | ## Livereload 480 | 481 | - 与nodemon的异同 482 | - webpack dev和hot插件 483 | - brower-sync 484 | - chrome插件 485 | - node和vue同构时,启动守护的,完成自动触发,类似于pm2机制 486 | - sockit.io同步处理,比如hade源码 487 | 488 | ## 代理:多环境下提高开发效率 489 | 490 | - 代理原理,http和https、中间人等 491 | - jsonp跨域 492 | - nginx转接口 493 | - hiproxy 494 | 495 | ## Bigpipe 496 | 497 | 麻雀虽小五脏俱全 498 | 499 | - 原理和例子 500 | - bigview 501 | - learn 502 | - yarn 503 | - es6语法 504 | - 浏览器渲染原理 505 | 506 | ## 优化移动端加载速度 507 | 508 | - App内置httpserver 509 | - webview注入 510 | - macaca 511 | - pwa和ssr 512 | 513 | ## 个人成长 514 | 515 | - 精力 516 | - 时间 517 | - 目标:技术or管理 518 | 519 | ## 有观点的八卦 520 | 521 | - node之父已死 522 | - uber换go 523 | - left-pad 524 | - 黑npm是黑洞 525 | - 版本帝 526 | - iojs到aya分裂 527 | - 回调地狱 528 | 529 | ## Node考证 530 | 531 | 待定 532 | 533 | - 考证 534 | - 考题 535 | - 重点 536 | 537 | ## 跨平台 538 | 539 | - pc:nw.js和electron 540 | - 移动端:cordova和ionic 541 | - web 542 | 543 | ## Api模拟与管理 544 | 545 | - api规范 546 | - api模拟 547 | - api管理 548 | - api网关 549 | -------------------------------------------------------------------------------- /q.md: -------------------------------------------------------------------------------- 1 | # Ask me anything in 《狼叔爱Node》 2 | 3 | 本仓库会持续更新,具体回复,请查看链接 4 | 5 | # 2017-02-24 6 | 7 | [回复内容](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=825114512512&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq&from=singlemessage) 8 | 9 | ## 问题1 10 | 11 | > 在一家创业公司实习,承担了比普通公司更多的职责和工作,但是我认为这种情况不应该持续下去。创业公司要向正规化的公司发展,必须要形成一个工程体系。产品不应该以需要跑业务为由而只留下一个只有概念的需求。现在技术团队已经完善了自己的技术体系。但是产品给出的需求依然只是一个概念性的东西。并且依然不做出改变。我学的是软件工程,我理解的工程是以团队为主题,每个人有自己的职责,工作流程十分清晰,输入输出十分明确,团队目标十分清楚,这样才能高效的运转,创业公司人少没办法,但是不应该在原地踏步,应该积极的向工程化团队的目标发展。在大公司工作的你们产品,设计,开发之间的关系是怎么样的?👀👀 12 | 13 | ## 问题2 14 | 15 | > nodejs如果只做后端开发的话,该如何在这条路上走的更远更好? 我本人不太喜欢搞前端开发,只想在后端发展。 16 | 17 | ## 问题3 18 | 19 | > 狼叔,您好。后端我只用过express + mongoose,想深入了解node.js后端,有什么源码demo可以推荐吗?😊 20 | 21 | ## 问题4 22 | 23 | > 狼叔你好,我之前跟着你的教程学的nodejs,受益匪浅。现在基本的语法都会了,也自己做了些留言板、博客之类的小网站。但是现在遇到了瓶颈,遇到大项目就不知从何下手。希望狼叔指点迷津~谢谢狼叔 24 | 25 | 26 | # 2017-02-27 27 | 28 | [回复内容](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=551225855554&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq) 29 | 30 | ## 问题1 31 | 32 | > 狼叔您好。我是一名雷达工程师,想做一个类似flightradar24的网站。现在雷达数据输出接口有网口和串口。请问这样的网站前后端怎么设计,数据怎么接入和存储?谢谢啦 33 | 34 | > 再稍微详细点,前端要啥,后端能给啥,大致的流程是啥,晚点统一回复 35 | 36 | > 前端实现飞机位置在地图上的实时显示,后端能提供雷达数据接口(网口或串口),接口实时输出飞机的位置高度速度等信息。总体上想做成flightradar24这个网站的样子。但是由于我之前是学硬件的,只学了一点网站的基础javascript ,html,node。还请狼叔多多指教 37 | 38 | ## 问题2 39 | 40 | 我是做php开发,在工作过程中,一直都是做业务逻辑开发。对于加载速度、并发,不是很了解。想请教一下node中是否也需要了解并发问题?会因为node是单线程 异步模式,就不需要了吗? 41 | 42 | ## 问题3 43 | 44 | 狼叔,我想问下,业务订单超时未付款自动关闭,一般是如何实现的? 45 | 46 | # 2017-03-02 47 | 48 | [回复内容](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=228828225811&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq) 49 | 50 | ## 问题1 51 | 52 | > 狼叔您好,本人刚毕业半年,有将近一年的node.js开发经验,最近准备去参加node.js面试的,我想问一下node.js面试中,面试官最喜欢问哪几类的问题,有哪一些"雷区"是不能踩的,请狼叔指明一条明路,不胜感激~~ 53 | 晚点统一回复 54 | 55 | ## 问题2 56 | 57 | > 狼叔,我在用idea 的debug模式时,报端口监听错误。代码里起了子进程,没让子进程监听端口。是不是idea的debug工具会让进程监听端口? 58 | 59 | ## 问题3 60 | > 狼叔可否聊一下测试的前世今生。为什么代码总要包含测试的部分?最近在学习promise的知识,其中有一章专门讲使用mocha进行promise测试。感觉不太理解,您是否可以形象的说一说呢 61 | 62 | # 2017-03-06 63 | 64 | [详细回复](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=145425855182&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq) 65 | 66 | ## 问题1 67 | 68 | > 桑大 问个问题 如果后台用python或者java专门提供数据 node如何去调用 69 | 70 | ## 问题2 71 | 72 | > 狼叔,最近李笑来的线上八周全栈班要开课,但是以rubyonrails为主。您可以比较一下和node的区别吗?如果报这个班,对全栈学习有多大帮助呢?我在google trend看rubyonrails在走下坡 73 | 可以写,不过会打起来😂 74 | 75 | ## 问题3 76 | 77 | > 继续请教狼叔关于flightradar24的问题,我现在通过wireshark可以读取雷达数据服务器输出的udp包雷达数据,并且在github找到了数据格式asterix parse的一个python的代码https://github.com/CroatiaControlLtd/asterix,麻烦狼叔帮忙看一下如何改用node实现,您给理个思路。还想请教狼叔读取文件的问题,我只会用fs模块读取文件,如何从网络读取或是从标准输入(比如电脑串口)读取,能可否推荐相关书籍或文章,不胜感激 78 | 79 | ## 问题4 80 | 81 | > 每次看github的代码都觉得一头雾水,不知怎么下手,请教各位大神们,你们是怎么阅读github里面代码的呢 82 | 83 | 84 | # 2017-03-09 85 | 86 | [统一回复](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=458558452158&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq) 87 | 88 | 89 | ## 问题1 90 | 91 | > 如下代码实现了一个使用mocha来检测是否返回了一个用户的测试用例const request = require('supertest')describe('GET /user/:id', function() { it('returns a user', function() { return request(app) .get('/user') .set('Accept', 'application/json') .expect(200, { name: 'John Math' }, done) })}) 92 | 93 | 上面写的测试用例,不知道意义何在。我觉得是,真正需要测试的大都是业务逻辑,比如游戏核心玩法算法这些,写个测试用例有很大的意义,可以验证算法是否正确。 94 | 95 | ## 问题2 96 | 97 | > 请问狼叔,现在node项目的代码使用ES6标准写还是用以前的? 98 | 99 | ## 问题3 100 | 101 | > 狼叔每天可否出几道思考题,这样能够指引大家慢慢覆盖node的知识点。之前的那一次就非常棒 102 | 103 | ## 问题4 104 | 105 | > 狼叔,对于用node 写手游服务器端,你有什么看法?或者有没有接触过的人,用node 在写服务器端的? 106 | 107 | ## 问题5 108 | 109 | > mongo不支持事务,狼叔有什么推荐的解决方案吗? 110 | 111 | ## 问题6 112 | 113 | > 一直有个疑惑,可能没有太在意。 今天想问下狼叔。大家都在说node.js的事件驱动,异步IO,概念都能倒背入流了,却依然没有掌握到精髓所在。 114 | 我的疑问在图片里,请狼叔解答。 115 | 116 | /** 117 | * 疑问: 118 | * 单机运行情况下 119 | * 120 | * 1: 并发请求过来的时候, 比如说req1, req2 ,是否这两个请求的func3 是按什么顺序注册到事件队列中的? 121 | * 2: 是否会因为并发,导致redis数据混乱? 我觉得应该会,io异步导致 122 | * 3: 所谓的单线程,是否就真的没有锁,同步的烦恼? 123 | */ 124 | 125 | 126 | # 2017-03-16 127 | 128 | [统一回复](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=228154214151&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq) 129 | 130 | ## 问题0 131 | 132 | 我基础知识不行,之前有js基础,然后看了一下node就开始写项目,边做项目边查资料,只是能把功能实现,理论知识欠缺,如果想补一下该看什么呢@i5ting 。求狼叔点拨一二 133 | 134 | ## 问题1 135 | 136 | 狼叔,您好!我想请问应届生找node.js实习工作难吗?没有经验简历应该怎么写?希望您能提供点思路给新人,谢谢! 137 | 138 | ## 问题2 139 | 140 | 这几天去面试了一些nodejs职位,被问得最多同时也是最基本的问题就是:你平时写node有没有什么经验心得。。狼叔请原谅我这个刚毕业没多久的node菜鸟,对于这一块确实没有累积到什么经验,所以想问一下,狼叔你们在开发nodejs项目的时候,最常遇到什么问题,如何去解决的,谢谢~ 141 | 142 | ## 问题3 143 | 144 | 请教大家,在使用formidable模块的时候,我发现如果在当前上传表单中并没有上传文件,那么在执行到form.parse()的时候会默认保存一个大小为0字节的空文件,请教该怎么避免这个问题? 145 | 146 | ## 问题4 147 | 148 | 狼叔,今天遇到一个问题,关于NodeJS能开辟多少个子进程的问题。具体场景:利用子进程来处理socket.io请求,想提高cpu的利用率,不知道开多少个子进程比较合适,目前是按照os.cpus().length来开辟的,但是不知是否能够重复利用cpu。最好的方法是重现真是的生产环境,然后根据cpu的使用情况来确定开辟的子进程数,但是这不现实。请狼叔指点一下,谢谢。 149 | 150 | ## 问题5 151 | 152 | 前段时间在V2看到TB的吐(招)槽(聘)贴,后来狼叔也在CNode整理了一番,但后期看到TB的严大回复“我们希望能招募到更多的应届生或工作一两年的后端新人”,当然,另一层意思是,3年左右的“老油条”第一成本不划算,第二我们的业务新人就搞得定,所以就不需要了;这让我有些困惑,最近由于公司这边的动荡才让我有了观望的想法,公司拖欠半月左右工资,从16年下半年开始已经有3次了,个人属于那种比较老实的那种,踏实干活、关注技术走向,不太感冒管理层的勾心斗角,但是感觉基本工资都不能保障,没有安全感;总结下:本人14年毕业就在这家公司,先后负责及时聊天、推送、微信服务号开发,到现在为止由于某些原因,想听下狼叔,关于“深度要扎实,适当的加点管理,尝试帮你的领导多分担活”这部分的详解。相信对于后端Nodejs走了3年左右的人来说是一个共性问题了。 153 | Ps:本人专业是计科(嵌入式方向),但由于刚毕业发现走硬件道路没有软件机会多,所以就投身到软件开发的队伍中了,Linux系统玩的很溜,甚至做过linux系统的裁剪和移植,所以才选择走后端而非前端,16年一段时间曾经做过一些简单前端开发,也做过php重构,但还是喜欢Nodejs,个人理念是不同需求、场景需要不同技术、语言,各个语言都有其擅长的地方和不灵的地方,不排斥java和php,能够灵活切换思维如果有需要的话; 154 | 155 | ## 问题6 156 | 157 | ``` 158 | 0 var request = require("request"); 159 | 1 160 | 2 var url = "http://localhost:3000/testRedisLock"; 161 | 3 162 | 4 for(let i = 0 ; i < 10; i++){ 163 | 5 requestServer(i); 164 | 6 } 165 | 7 166 | 8 function requestServer(index){ 167 | 9 request.post({ 168 | 10 url: url, 169 | 11 form: { 170 | 12 index: index, 171 | 13 time: Date.now() 172 | 14 } 173 | 15 }, function(err){ 174 | 16 }); 175 | 17 } 176 | 177 | 178 | function testRedisLock(req,res) { 179 | //测试redis原子性的分布式锁 180 | console.log('time-start: ', req.body.time); 181 | var jackPotDiamond = 0; 182 | var autoFillTimes = 0; 183 | var fillDiamond = 10; 184 | 185 | var log = { 186 | index: req.body.index, 187 | time: req.body.time, 188 | step : 0 189 | }; 190 | 191 | async.waterfall([ 192 | function (cb) { 193 | redisUtil.getRedisData(POT_KEY, function (err,data) { 194 | if(!err && !!data){ 195 | jackPotDiamond = parseInt(data); 196 | } 197 | cb(err); 198 | }); 199 | }, 200 | function (cb) { 201 | log.oldJackPotDiamond = jackPotDiamond; 202 | jackPotDiamond += 10; 203 | log.jackPotDiamond = jackPotDiamond; 204 | redisUtil.setRedisData(POT_KEY, fillDiamond, function (err) { 205 | if(!!err){ 206 | log.step = 1; 207 | } 208 | cb(err); 209 | }); 210 | }, 211 | function (cb) { 212 | redisUtil.getRedisData(AUTO_FILL_TIMES, function (err,data) { 213 | if(!err && !!data){ 214 | autoFillTimes = parseInt(data); 215 | } 216 | cb(err); 217 | }); 218 | }, 219 | function (cb) { 220 | log.oldAutoFillTimes = autoFillTimes; 221 | autoFillTimes += 1; 222 | log.autoFillTimes = autoFillTimes; 223 | redisUtil.setRedisData(AUTO_FILL_TIMES, autoFillTimes, function (err) { 224 | if(!!err){ 225 | log.step = 2; 226 | } 227 | cb(err); 228 | }); 229 | }, 230 | function (cb) { 231 | redisUtil.INCRBY(AUTO_FILL_DIAMOND, fillDiamond, function (err) { 232 | if(!!err){ 233 | log.step = 3; 234 | } 235 | cb(err); 236 | }); 237 | } 238 | ],function (err) { 239 | if(!!err){ 240 | log.error = err; 241 | } 242 | console.log('autoFillJackPot: ', req.body.time,log); 243 | return res.send({info : log}); 244 | }); 245 | 246 | for 循环执行了100次, 然而结果确实 247 | autoFillJackPot: 1489131722216 { index: '93', 248 | time: '1489131722216', 249 | step: 0, 250 | oldJackPotDiamond: 0, 251 | jackPotDiamond: 10, 252 | oldAutoFillTimes: 0, 253 | autoFillTimes: 1 254 | } 255 | 除了index是递增的,redis拿到的数据以及更新的数据 都跟第一次执行结果一致。 256 | 257 | 我的理解就是,当大量的并发请求到服务器的时候,redis是需要加锁的,否则,数据就会出现错误。 258 | 虽然redis单个操作是具有原子性的也只是对一个操作具有原子性,不是对请求处理过程具有原子性。 259 | ``` 260 | 261 | ## 问题7 262 | 263 | 狼叔,为什么写测试用例的时候要一条一条的写,而不是 按照功能模块一块撸了。 264 | 265 | # 2017-03-21 266 | 267 | [回复内容](https://wx.xiaomiquan.com/mweb/views/topicdetail/topicdetail.html?topic_id=228148512581&secret=nz1g98h4s9mjd46jzu0tbx7blebu4enq) 268 | 269 | ## 问题6 270 | 271 | 狼叔 我有个可能不太成熟的心理 觉得现在前端圈有个很怪异的现象,大家都用github分享些自己的项目 272 | 当去看了对方的项目后,发现其实功能很简单,但是项目里却用了很多的库 273 | 每个库依赖的库又有好几个,想想也是浪费。 274 | 275 | 有时候在cnodejs上看些内容真的很不自在,看到一个项目想去研究下,想看看别人的思路,结果核心部分一堆库的调用,很希望看到的是大家都有自己的想法,而不是每次都是推荐库,感觉大家都要被各种库剥夺自己了 276 | 277 | 答 278 | 279 | 学些都是先散的点,然后放到一起。比如练字,刚开始都是单个字,后面才是谋篇布局、章法类的。所以上来就写,肯定是特别难得。 280 | 281 | 对于开源项目也是一样的,所以理解了上面的原理,其实你就可以非常简单的逆推了。先把package.json的里的每个模块都玩明白了。然后再玩拼起来的,就会比较容易一些。避免上来大而全,对新手不利。 282 | 283 | 最小化是学习最好的方法。能够从复杂的项目里扒出有用的东西,更是本事。加油 284 | 285 | ## 问题1 286 | 287 | 请教一下 狼叔 node作为后台为app提供接口的过程中,出现内存泄漏的问题,如何处理?我理解的是如果是客户端会有浏览器进行处理了,那服务器端如何处理? 288 | 289 | 290 | ## 问题2 291 | 292 | async/await和promise的问题 293 | 294 | 1,现在是promiseA+规范,但我不清楚node.js原生promise是怎么实现的?是通过emit还是setTimeout,还是process.nextTick实现的? 295 | 2,async/await的本质是generator吗?是generator的语法糖吗?如何理解async/await和promise的关系? 296 | 3,第三方bluebird或Q包,他们实现promise的方式和原生promise是一样的吗? 297 | 还望狼叔解疑一下,最近这块有点疑问。。。 298 | 299 | ## 问题3 300 | 301 | 请教狼叔怎么用vscode进行node调试,有两个问题: 302 | 303 | - 1、图片中的第二个断点一直走不进去,第一个断点可以,是我的方式不对还是说这是因为node异步的原因? 304 | - 2、用vscode调试怎么进行post调试,比如提交表单数据,也就是怎么能和网页操作挂钩,比如像ASP.NET那样? 305 | 306 | ## 问题4 307 | 308 | 狼叔,请问这种方式exports是什么意思,特别是这部分 (function (Base62) {}({})); 309 | 310 | ``` 311 | code: 312 | module.exports = (function (Base62) { 313 | var DEFAULT_CHARACTER_SET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 314 | 315 | Base62.encode = function(integer){ 316 | if (integer === 0) {return '0';} 317 | var s = ''; 318 | while (integer > 0) { 319 | s = Base62.characterSet[integer % 62] + s; 320 | integer = Math.floor(integer/62); 321 | } 322 | return s; 323 | }; 324 | 325 | Base62.decode = function(base62String){ 326 | var val = 0, base62Chars = base62String.split("").reverse(); 327 | base62Chars.forEach(function(character, index){ 328 | val += Base62.characterSet.indexOf(character) * Math.pow(62, index); 329 | }); 330 | return val; 331 | }; 332 | 333 | Base62.setCharacterSet = function(chars) { 334 | var arrayOfChars = chars.split(""), uniqueCharacters = []; 335 | 336 | if(arrayOfChars.length != 62) throw Error("You must supply 62 characters"); 337 | 338 | arrayOfChars.forEach(function(char){ 339 | if(!~uniqueCharacters.indexOf(char)) uniqueCharacters.push(char); 340 | }); 341 | 342 | if(uniqueCharacters.length != 62) throw Error("You must use unique characters."); 343 | 344 | Base62.characterSet = arrayOfChars; 345 | }; 346 | 347 | Base62.setCharacterSet(DEFAULT_CHARACTER_SET); 348 | return Base62; 349 | }({})); 350 | ``` 351 | 352 | ## 问题5 353 | 354 | 狼叔,更了不起的Node4这本快点大概什么时候能出呀,好想买一波。。。。 355 | 356 | 答 357 | 358 | 月底会公测,大家参与吧 359 | 360 | ## 如果想提问,请加入《狼叔爱Node》群,有问必答 361 | 362 | > 互相尊重,坦诚,不说没用的 363 | 364 | 《狼叔爱Node》是我在小密圈上创建的私密沟通群 365 | 366 | - 主要内容涵盖Node、全栈、开源三大部分 367 | - 偶尔发点感想、备忘、笔记类的,会有不想公开的哦 368 | - 方便沟通,可以直接提问,应急支援,解答疑问、点评 369 | - 更有justjavac、fundon、老雷,nswbmw、alsotang等大神陪伴 370 | 371 | 会员策略 372 | 373 | 前100名99元/年,之后恢复正常价格199元/年 374 | 375 | ![Connect](connect.jpg) 376 | 377 | 378 | 379 | --------------------------------------------------------------------------------