当前位置: 首页 > news >正文

需要做个网站自己做优惠券网站

需要做个网站,自己做优惠券网站,怎么选择合适的网站开发公司,建设网站首页应该采用1.引言 最近参加了大量的招聘会#xff0c;投递了大量的简历#xff0c;整整体会了从“随便找个厂上一下”——“还是的找个大厂”——“没人要”——“急了急了,海投一波”——“工资有点尬”——“海投中…”。简单说一下自己的一些感受吧#xff0c;现在的前端属实有点尴…1.引言 最近参加了大量的招聘会投递了大量的简历整整体会了从“随便找个厂上一下”——“还是的找个大厂”——“没人要”——“急了急了,海投一波”——“工资有点尬”——“海投中…”。简单说一下自己的一些感受吧现在的前端属实有点尴尬 前端的基础教程特别多最开始本来是觉得自己有这断断续续3年的编程经历还算有优势可惜很多公司需要的是那种把面试玩明白的知道后来我才发现原来前端是有着一个30w字的简历总结的那里面涵盖了大量的前端面试题甚至基本上我参加的面试或者笔试都有相关的题目。我面过多益网络这厂背后总有一股不是很让人向往的知乎风评多益网络的面试虽然可能繁杂一下但是多益问的基础还是比较广泛的更加适合那些从前端还没有炸就开始学的面过一些类似“冲业绩的”懂的都懂还有一些直接拿着双飞本科说事的。 2.一点点体会 总结一下就是前端教程很多都偏向于应用上实际上公司需要的是那一种能够深挖原理的比如可以看看《你不知道的JavaScript》技术群别人推荐的如果现在还不懂原理的话找到理想工资的前端工作还是很有难度的。     大概说一下我个人的情况吧本科双飞强调这个可能学历高的没有体会到这个的劣势一谈工资面试官就会拿学历压薪资然后大学生创新创业和同学组建过公司这大概算得上自己最耀眼的经历吧然后过了六级分不高专业差不多前十当然不保研这个实际作用应该不大然后动手能力可能强一些在公司的时候一起接过外包自己也接过学妹学弟的单子虽然钱不多差不多几天一个全栈小demo的那种。实际上面试官可能比较烦这种写demo影响编码规范也是有可能的。主要是可能因为自己去年四月份选择了考研然后在经验上或者是技术变化的跟随上有一些不足这里我觉得更为核心的还是实习经验上自己创新创业的一年好像不是很能够被认可但是在我个人看来其实面试我的公司的开发部还没有我们当时的那个人数多。     我这里不是要批斗什么也不是报一种就业消极的心态面试其实也有它的好处。比如给我影响深刻的是能够提高我们的技术基础长期写代码的人可能更能体会到学的东西很快会忘导致问什么可能当时想不起来但是给个机会几分钟搜一下就能明白比较经典的就是某个公司问我的axios拦截重复请求问题。还有一些公司的面试官比较友好他们会暗示性的让你回答他想要的答案比如真的吗这个时候往往就是你错了你得记下来回去试试、搜一搜、再积累积累。更好一下的面试官直接给你讲解少量的知识里面很多都是你理解错了的或者理解不充分的比如多益的JSON.parse()拷贝的浅拷贝的理解一零跃动promise的then方法其实有着第二个参数err触发到catch。还有就是面试的碰壁能够激励自己去学历更多的理论知识总不能一家不知道直接下一家也不知道吧想想都觉得尬面试官还能够提示一些关键词比如快狗打车的ast抽查diff模板渲染等在外界的刺激下确确实实能够学习更多理论。从想——搜——敲/复制——调试——经验积累什么可以实现需要借助什么转变为想——涉及原理——封装——优化——编码决策。 3.建议 如果找工作的话建议还是多看看理论当然编码能够加强记忆和理解。如果你已经有很好的编码经验建议还是多看看原理那才是提高薪资的敲门砖。如果你觉得不能够很好的表达多看看原理相关的文章比如去大佬的公众号或者是掘金csdn更偏向于代码编写和框架依赖的使用至少热度上是这么表现的。 4.面试难题总结 今天就花点时间把这些原理给学了不再下次一定。主要包括如下几点 1原型和原型链 2koa原理 3promise原理 4nodejs模块化原理 5node events 如果有不对的欢迎在评论区指点指点带我一手非常感谢。 4.1原型和原型链 可能你在layui的部分源码中看到过知道它是用来挂载属性和函数的但这过面试还不够。原型和原型链其实还牵扯了JS内部很多的概念问题constructor、函数、对象、prototype、_proto_、原型对象、原型、原型链。     object.constructor也就是拿到一个对象的构造函数函数和对象有一种说话是“函数即对象”Function 函数和Object函数都是JS内置对象内部类函数其实就是Function这个内置对象的实例对象因此说函数即对象。函数与对象的区别功能上函数强调对一种操作的封装对象则更强调实例更偏向于是一个功能被丰富的变量。     prototype出现的原因当我们使用一个对象构造出两个不同的实例对象然后给实例对象分别挂载上相同的方法由于被挂载的方法分属于不同的对象那么对出现student1.getName() ! student2.getName();同时带来的问题是直接占用了两块内存空间这么玩的话也有点尬明显封装度不是很够还有比如我们利用Array引用对象构造了一个arr的实例对象这个实例就可以使用到pop、push、splice等一系列方法其实就是prototype的作用也就是常理解的挂载属性和方法     原型对象即创建自己的构造函数所在的类中的prototype接下来分析一下constructor的属性的位置既然constructor在每个实例对象都可以获取到那刚好可以把这个constructor挂载到prototype里面实际上恰好也是这么处理的。然而问题来了是否可以中途修改constructor达到修改所有的答案是不能 这个时候__proto__就来了那就能够指向原型对象的prototype也就是原型对象 接下来再来理解原型链就轻而易举啦student1的 __proto__可以指向其构造函数内部的prototype属性原型对象这玩意本身它就是一个对象并且是一个Function类构造的实例那么Function本质又是Object类构造的因此就能够一步步向上查找原型对象这就是所谓的原型链student1.__proto__可以找到Student.prototype student1.proto.__proto__可以找到new Student函数的原型也就是Object.prototype,为了里面原型链的循环取对象的原型为null 4.2 koa原理 这个题目确实有些难经过一些尝试我把我的理解分享出来官网上主要是介绍一些基本信息 差不多说的是koa是一个开发express的团队设计的新的web框架以更小更快更健壮为目标来搭建web应用或者是api可以摆脱回调的使用增加错误处理核心部分没有捆绑任何中间件能够更优雅的写服务端应用。像没说一样需要关注的还是原理经过一些文章的学习明白了koa的核心文件application.js、context.js、request.js以及response.js分别针对应用搭建、上下文ctx请求体和响应体。结构图如下 aplication继承nodejs里面的events模块用于事件统一管理的对应第五个先不细说简单说一下程序执行流程由application里面封装的listen方法结合调用new koa().listen 传入的参数来开启一个nodejs服务接着处理middleware中间件然后将洋葱模型串联起来并执行返回响应。这里先挖一下洋葱模型的实现原理为什么要是用洋葱模型其实我并没有找到我能接受的答案网上说的是能够保证中间件的顺序执行为什么会顾及中间件的这个执行呢因为中间件之间可能会存在相互引用使用洋葱模型结合koa-compser里面的promise串联机制能够保证函数的顺序执行可能也是为了抽离出思想或者是借鉴了某些非计算机领域的思想来这么称谓的吧我觉得这个概念有点强制话主要是因为在koa里面的middleware只有一个next能够调用下一个中间件并没有说能够自由调用内部中间件因为自己经验还是比较有限可能对于代码思想上的概念还缺乏相当程度的理解 于是找来了一个项目看看尝试理解 是否觉得还可以挣扎一下对将middleWare强行用一个函数套在一起返回当然实测发现不行因为已经脱离了koa框架的执行机制和对外暴露的接口了。这样就能够举例证明middleware之间顺序执行的必要性但诚然无法说明洋葱的重要性不过相比于顺序执行而言next的参与能够像nextTick()一眼获得到下一个middleware的数据然后next的调用者内部能够进一步利用更新后的ctx进行后续处理。还是拿着这段经典代码来解释洋葱模型的顺序化处理吧并没有在实际开发中真正使用到说真的理解起来不是很顺畅 const koa require(koa); const app new koa(); app.use(async (ctx, next) {console.log(1);next();console.log(5); }); app.use(async (ctx, next) {console.log(2);next();console.log(4); }) app.use(async (ctx) {console.log(3);ctx.body hello world; }) app.listen(3000, () {console.log(服务启动localhost:3000); }) //输出12345其实就是利用了promise的异步执行特点将next封装成一个promise对象然后利用递归来实现还是看看源码吧 现在将核心放在递归链上上面这个递归的理解也需要花点时间我们先易后难将函数简化成 const koa require(koa); const app new koa(); app.use(async (ctx, next) {console.log(1); }); app.listen(3000, () {console.log(服务启动localhost:3000); })在只有一个middleware的情况下函数步入肯定会到达上图代码的42行但由于函数在next处没有执行过因此直接退出下面恢复next的使用函数步入由于这次next执行函数递归就形成了嵌套相当于将下一个中间件塞到了前一个中间件内部这里则不是由于imiddleware.length跳出的而是函数正常执行而结束的所以这个函数其实算是一种伪递归。接下来分析为什么函数能够检测出来两次next()两次next的限制可能是为了防止嵌套深度过大假设在上面最简单的代码中加上两次next那个只打印1的代码块那么还是一样模仿函数执行函数步入之后也就是会重复调用两次depatch(1)也就是会出现第二次的时候iindex的情况。     回到面试上来如果再次遇到了这个问题该怎么回答呢     答koa主要是利用promise异步编程抛弃回调函数不再内置中间件其中主要包含四大模块分别是applicationcontext、request、response在application中封装了一个构造函数在继承了nodejs的events模块的同时对外暴露了listen、use、toJSON等接口listen内部又基于nodejs的原生http模块封装了nodeServer函数利用use来装载外部自定义的中间件在中间件机制上koa使用洋葱模型的思想先将多个middleware中间件顺序存到一个数组中然后再利用koa-compose里面的compose方法来保证middleware能够顺序执行在compose方法中其实利用的是递归的思想对middleware函数进行遍历同时将函数的next参数修改为执行下一个middleware的函数当然存在一定的爆栈风险可以改用倒序遍历中间件的方式重新封装compose方法。对于request和response上采用的是类似于Vue的getter、setter来设置和修改request和response上面的属性同时结合delegate将request和response代理到context上面方便获取和函数调用。 4.3 promise原理 面试官特别喜欢问这个但我总觉得的不是很好回答(甚至直接被误解为只是使用过一般听到这儿那你的promise基本就算是没答上来)手写promise也搞过但不怕被笑话我是背的源码下面再好好总结总结。首先总结一下promise的特点 1promise一共有三种状态pending、Fulfilled、Rejected 2promise接受一个函数作为参数该函数又具有resolve和reject两个函数类型参数resolve函数能够将pending状态转变成Fulfilledreject函数能够将peding状态转化成Rejected在状态转变之后立即触发相对应的then和catch函数也就是说代码中同时有resolve和reject调用的话谁在前面调用就谁说了算最后如果有finally的话只要转变了都触发 3注意一点(某次被面试官刷新认知)promise的then方法里面是有两个参数的包括成功的处理方法还有失败的处理方法如果在成功中调用抛出异常那么函数可以进入catch这个本质是promise内部做的异常处理如果是reject并且在then里面写了第二个函数即错误处理函数那么catch不会触发并且如果是在then的错误处理函数抛出错误也不会触发catch其实这是因为catch本质是一个语法糖还是通过调用then里面的方法来实现的也就是这样也就很好理解了建议还是不要使用then的第二个参数否则这个语法糖的意义也就不大了代码清晰它不香吗 Promise.prototype.catch function(fn){return this.then(null,fn); }4promise在执行的过程中支持链式调用promise.then可以一直向下调用就算是中间某处的then或者catch函数有问题也能将状态向下传递就简单举个例子吧 面试官问的话把这些答出来基本就差不多了友好一点的面试官可能会问你“聊聊promise吧”不友好的“promise的原理是什么”这么问有点尬异步编程确实就是这样的有点无从下口但是你就把你的理解说出来应该问题不大或者面试官没有听到想要的答案也会转入你喜欢的问答模式。接下来再来说说promise的手写问题了解以上就比较好理解了特别是关于为什么进行回调函数的数组封装我怕自己写的不够完美借鉴了掘金的大佬的代码然后微调了一下 const isFunction variable typeof variable functionconst PENDING PENDINGconst FULFILLED FULFILLEDconst REJECTED REJECTEDclass MyPromise {constructor(handle) {if (!isFunction(handle)) {throw new Error(MyPromise must accept a function as a parameter)}this._status PENDINGthis._value undefinedthis._fulfilledQueues []this._rejectedQueues []try {handle(this._resolve.bind(this), this._reject.bind(this))} catch (err) {this._reject(err)}}// 添加resovle时执行的函数_resolve(val) {const run () {if (this._status ! PENDING) returnconst runFulfilled (value) {while (this._fulfilledQueues.length) {this._fulfilledQueues.shift()(value);}}const runRejected (error) {while (this._rejectedQueues.length) {this._rejectedQueues.shift()(error);}}//判断是否是resolve的参数为Promise对象if (val instanceof MyPromise) {val.then(value {this._value valuethis._status FULFILLEDrunFulfilled(value)}, err {this._value errthis._status REJECTEDrunRejected(err)})} else {this._value valthis._status FULFILLEDrunFulfilled(val)}}// 为了支持同步的Promise这里采用异步调用setTimeout(run, 0)}// 添加reject时执行的函数_reject(err) {if (this._status ! PENDING) returnconst run () {this._status REJECTEDthis._value errwhile (this._rejectedQueues.length) {this._rejectedQueues.shift()(err)}}// 为了支持同步的Promise这里采用异步调用setTimeout(run, 0)}then(onFulfilled, onRejected) {const { _value, _status } this// 返回一个新的Promise对象return new MyPromise((onFulfilledNext, onRejectedNext) {// 封装一个成功时执行的函数let fulfilled value {try {if (!isFunction(onFulfilled)) {onFulfilledNext(value)} else {let res onFulfilled(value);if (res instanceof MyPromise) {// 如果当前回调函数返回MyPromise对象必须等待其状态改变后再执行下一个回调res.then(onFulfilledNext, onRejectedNext)} else {//否则会将返回结果直接作为参数传入下一个then的回调函数并立即执行下一个then的回调函数onFulfilledNext(res)}}} catch (err) {// 如果函数执行出错新的Promise对象的状态为失败onRejectedNext(err)}}// 封装一个失败时执行的函数let rejected error {try {if (!isFunction(onRejected)) {onRejectedNext(error)} else {let res onRejected(error);if (res instanceof MyPromise) {// 如果当前回调函数返回MyPromise对象必须等待其状态改变后再执行下一个回调res.then(onFulfilledNext, onRejectedNext)} else {//否则会将返回结果直接作为参数传入下一个then的回调函数并立即执行下一个then的回调函数onFulfilledNext(res)}}} catch (err) {// 如果函数执行出错新的Promise对象的状态为失败onRejectedNext(err)}}switch (_status) {// 当状态为pending时将then方法回调函数加入执行队列等待执行case PENDING:this._fulfilledQueues.push(fulfilled)this._rejectedQueues.push(rejected)break// 当状态已经改变时立即执行对应的回调函数case FULFILLED:fulfilled(_value)breakcase REJECTED:rejected(_value)break}})}// 添加catch方法catch(onRejected) {return this.then(undefined, onRejected)}// 添加静态resolve方法static resolve(value) {// 如果参数是MyPromise实例直接返回这个实例if (value instanceof MyPromise) return valuereturn new MyPromise(resolve resolve(value))}// 添加静态reject方法static reject(value) {return new MyPromise((resolve, reject) reject(value))}// 添加静态all方法static all(list) {return new MyPromise((resolve, reject) {let values []let count 0for (let [i, p] of list.entries()) {// 数组参数如果不是MyPromise实例先调用MyPromise.resolvethis.resolve(p).then(res {values[i] rescount// 所有状态都变成fulfilled时返回的MyPromise状态就变成fulfilledif (count list.length) resolve(values)}, err {// 有一个被rejected时返回的MyPromise状态就变成rejectedreject(err)})}})}// 添加静态race方法static race(list) {return new MyPromise((resolve, reject) {for (let p of list) {// 只要有一个实例率先改变状态新的MyPromise的状态就跟着改变this.resolve(p).then(res {resolve(res)}, err {reject(err)})}})}finally(cb) {return this.then(value MyPromise.resolve(cb()).then(() value),reason MyPromise.resolve(cb()).then(() { throw reason }));}}4.4 nodejs模块化原理 node的应用是模块组成的Node遵循commonjs的模块规范用来隔离每一个模块的做用域使每个模块在自身的命名空间中执行。这也是面试遇到的一大原因光会用一些内置模块和第三方依赖远远不够提到模块基本每个语言都有在js中还有一种es6模块了解二者的区别也是必要的 1导入导出语法上不同CommonJS 使用的是 module.exports {} 导出一个模块对象require(‘file_path’) 引入模块对象ES6使用的是 export 导出指定数据 import 引入具体数据。由于前端一般是es6后端一般是CommonJS仔细回想一下编程时候使用的导入导出不难理解需要注意的是后端也是可以通过package.json文件配置不同的编规范的开发规范其实有很多不过这两种算是比较常用的es6的模块化其实还依赖于babelbabel能够将还未被宿主环境兼容的es6模块编译成es5CommonJSwebpack中就用到了babel-loader处理兼容性问题。 2模块输出上的区别CommonJS 模块输出的是一个值的拷贝ES6 模块输出的是值的引用也就是CommonJS输出之后不再受到模块内部变化的干预而ES6则会改变 3模块加载上CommonJS 模块是运行时加载ES6 模块是编译时加载CommonJS先加载整个模块并生成对象然后读取对象上的方法而ES6则不需要加载整个模块利用import加载指定值     还是回到问题上来如果面试官问什么是nodejs的模块化其实是考察是否看过官方文档是否了解框架底层工具的原理.     你可以这么回答在nodejs中每一个文件都被视为一个模块然后利用nodejs的模块包装器函数保证每一个模块的变量的作用域范围只限制在模块内部在导出时nodejs会利用module.exports函数类挂载函数或者变量等模块除了exports属性外还有模块id(通常就是模块解析后的文件名)、被调用的子模块children和调用者parent、模块搜索路径path、模块完全解析路径filename以及标识模块是否加载完成的loaded。nodejs中的模块一共被分为三类系统内核模块、用户自定义模块以及第三方模块。在一个模块调用另一个模块中的函数时会使用require函数来引入具体流程是首先查看文件模块中是否有缓存模块在第一次加载之后进行缓存如果有缓存直接使用如果没有则判断是否是内核模块如果是内核模块加载、缓存并使用如果不是需要查找文件模块的位置在这个过程中需要分情况来加载如果是有相对路劲标识那么直接定位相对路径指向的位置加载如果是第三方模块那么会在package.json的main属性下指定文件通常是app.js的同级目录的node_modules下找没有找到再一步一步再上一级的node_modules中找没有找到则返回查找失败报错。相对路劲下如果没有文件后缀会利用.js、.json、.node依次补充查找如果判定为第三方包还是会找package.json中的main属性指定的文件名不成功则找index.js,index.node,index.json类似于php的默认查找。     这个可能还是不够面试官可能追问如果模块之间相互依赖构成了依赖环怎么办——其实nodejs自己处理了出现循环依赖主要是模块之间的相互引入nodejs会返回其中一个模块加载未完成的副本当然还有可能问到一个问题既然是缓存那这个缓存怎么刷新什么时候失效呢有多种缓存策略可以了解一下这里不再详细描述强制刷新缓存的话可以利用这句delete require.cache[require.resolve(module)];。 4.5 node events 感觉这个问的我挺惭愧的基本用的都是常用模块对框架工具的探索或者说是官方文档的阅读明显不足。其实这个也是让你讲讲events的用途。前面提到了koa中直接继承了events模块从侧面也可以看出events的完善和强大。     其实nodejs是事件驱动非阻塞io构建的所谓的事件驱动指的是通过有效的方法来监听状态状态变化了触发响应事件什么是非阻塞io这里然后我想起了有一次面试题里面问到了阻塞io与非阻塞io的区别阻塞io指的是需要内核IO操作彻底完成后才返回到用户空间执行用户的操作。而非阻塞指的是用户空间的程序不需要等待内核IO操作彻底完成可以立即返回用户空间执行用户操作即处于非阻塞的状态与此同时内核会立即返回给用户一个状态值就比如nodejs一大优点为处理io密集型工作。     事件模型使用的是发布订阅模式在vue的响应式原理中也经常被提到在实时消息系统中也经常用到另外websocket和mqtt协议在使用时也会经常被提到。先给出一个使用例子吧     一下子就能想到第一个用途增强系统的维护能力在每次有错误的时候能够打印错误日志甚至还能够借助邮件系统相关的第三方依赖直接发送邮件反馈系统的错误信息及时对系统进行维护。另外可以联想到vue里面的子组件像父组件传参跨模块倒是不如回调函数来的直接当然把监听器导出去也可以但是一个模块内部进行传参监听还是可以的但也需要注意另外一些问题传来传去太多了系统容易像goto一样另外监听器还是容易产生一些性能和内存泄漏上的顾虑不同的时候及时剔除或者参考下面的常用api最贴切的使用 emitter.on(eventName, listener)//添加指定事件的监听 emitter.emit(eventName[, ...args])//触发事件 emitter.once(eventName, listener)//绑定一次性监听类似于vue的v-once emitter.eventNames()//获取监听器监听的事件的名称 emitter.getMaxListeners()//获取能够设置的监听器上限 emitter.setMaxListeners(n)//设置监听器 emitter.listenerCount(eventName)//获取当前监听器的数量 emitter.listeners(eventName)//获取监听某事件的监听器副本 emitter.addListener(eventName, listener)//追加监听器 emitter.prependListener(eventName, listener)//头插监听器 emitter.prependOnceListener(eventName, listener)//头插一次性监听器 emitter.removeAllListeners([eventName])//不再监听某事件 emitter.removeListener(eventName, listener)//一处指定监听器对指定事件的监听这个其实和dom事件比较类似该有的方法都有自定义能力强大甚至有了数组的功能在面试的时候如果没有使用过也要挣扎一下比如我虽然没有在项目中真正使用过但是我知道…可以怎么样有哪些方法等就和打游戏一样“射手被人抓总不能一直逃吧你说两句还能在薪资上回个血”。 5.求职反问阶段的问题 我很幸运考完研之后有很多好兄弟都入职了大厂他们给我了很多指点下面给出一些反问面试官的话语 1表示出你很希望加入公司问一些关于项目的团队情况培训方式、入职大概的工作等 2如果你很在意薪资不要有什么顾虑虽然有些面经觉得这个有些敏感了因为背后会有人根据面试情况给你定薪资比如B站的模拟面试咱找工作这个都不问有点傻乎乎的至少自己得有个薪资的线你可能怕问了别人不给offer不给就不给下一家 3五险一金中公积金的比例根据根据好兄弟介绍这里面大概有个1w左右的钱 4住宿和就餐问题毕竟这也关系到能够攒下多少钱 注每次别人给了面试机会最好把相关的网络信息搜集一下比如知乎风评、薪资、工作氛围等都初步了解一下不要套路式的反问反而可能让别人觉得你有点憨等下给你来句我们校招简章里面有说明的你可以去看看嘿嘿什么意思应该懂了吧。
http://www.w-s-a.com/news/81765/

相关文章:

  • 公司展示网站模板模板工
  • 网站建设收费详情舟山公司做网站
  • 深圳宝安区住房和建设局网站html模板大全
  • 和田哪里有做网站的地方wordpress地址更改
  • 恒通建设集团有限公司网站企业网站百度指数多少算竞争大
  • 雅虎网站收录提交入口如何使用wordpress搭建网站
  • 微商城网站建设怎么样发稿是什么意思
  • dz建站与wordpress群晖做网站服务器速度快吗
  • 做手机网站的公司网站建设 app开发 图片
  • 网站开发技术背景介绍wordpress数据库重置密码
  • 开发建设网站的实施过程是一个logo设计品牌
  • 做360pc网站排名首页工程造价信息网官网首页
  • 产品销售网站模块如何设计大数据和网站开发
  • 现在帮别人做网站赚钱不济南做网站建设公司
  • 嘉兴网站建设哪家好最近三天的国际新闻大事
  • 安丘网站建设制作做网站口碑比较好的大公司
  • 成都专业做网站公司哪家好优化大师下载安装免费
  • 防蚊手环移动网站建设广东深圳有几个区
  • 网站建设找哪些平台宜兴网站开发
  • 免费网站应用软件wordpress添加动态图标
  • 中小企业网站建设客户需求调查问卷昆明网站建设一条龙
  • 网站内容的特点wordpress 移动端网页
  • 专门网站建设培训网站系统建设
  • 自己设计手机的网站wordpress主题加密教程
  • 北京网站建设公司飞沐卖水果网站建设的策划书
  • 北京免费自己制作网站短视频宣传片制作
  • 怎样进入谷歌网站电子商务网站建设软件选择
  • 建个普通网站多少钱设计师培训多少
  • 建设校园网站的意义视频链接提取下载
  • 天津电子商务网站wordpress安装图片