㈠ 前端面试时被问到前端布局,这个怎么回答
前端面试时被问到前端布局,这个怎么回答
你可以说,你对DIV+CSS布局的了解,不懂你先网络吧,我不可能一一说明的。
然后说,盒子模型的了解,还是那句,不懂你网络吧。
然后说,清除浮动的了解,还是那句,不懂你网络。
然后说,内联、内联块和内联元素的了解。
还有一些加分的,例如overflow的深入理解。overflow,如果理解得深入,对布局有一定的影响。
差不多就这样了,面试官也许问得更细,我就不清楚了。
前端面试,被问到vue的元件是怎么写,我怎么回答
vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,….. export 。场景有:单页应用中,元件之间的状态。音乐播放、登入状态、加入购物车
web前端面试被问到为什么离职
实话实说,但是注意言辞,回答过程中千万不要抱怨、或是“吐槽”前东家的种种不好,请客观磨模悄地叙述与自己现在状态有哪些不相契合的点。
参考:原东家的发展空间达不到我的期望,我想要寻找新的机会挑战自己,同时创造更大的价值。
注意:避免假大空的官话,会让人觉得不真诚,另外,点到为止,无需细谈。
前端面试时问到:怎么解决浏览器相容性?该怎么回答比较码型好?
IE6/IE7对FE当然很不友好,但专业的FE决不应该因为这两个浏览器难处理就不处理了。假如使用者需要,我的目标是在力所能及的情况下为使用者提供最好的前端展现。相容性的问题从来都不只是IE6/7的问题,各个手机、浏览器、版本的相容性同样有各种各样的问题,比IE奇葩多了。我的经验是,每遇到一个坑爹问题,做这么几件事:确认触发场景,什么浏览器、版本、什么情况下会出现这个问题,做到稳定复现;找到问题原因,为什么会出现这样的问题(网上搜、自己琢磨甚至邮件问相应公司开发者等等都是可行的);确瞎渣定解决法,有没有什么框架级的解决法,总之是定规范,避免类似问题;比如不使用某些属性;用某种布局方法规避一些问题等等;有没有什么临时的法可以快速绕过去?不是每次都有时间搞框架级的法来着。怎么hack过去把这些都积累起来,就会有用处。不要想着IE6、7没了就不用考虑浏览器相容性问题,chrome/firefox、webkit的各种版本,手机的各种浏览器、各种终端都要处理浏览器相容性问题,恩,对,偶尔还有flash来着。相容各种终端、相容各种分辨率、相容浏览器都是相容性问题,这是FE的命,得认。抱着让使用者有最好体验的想法去做,收获更大。
前端面试被问到,vue实现资料双向系结,原理是啥
其原理大致是这样:
在资料渲染时使用prop渲染资料
将prop系结到子元件自身的资料上,修改资料时修改自身资料来替代prop
watch子元件自身资料的改变,触发事件通知父元件更改系结到prop的资料
这样做的好处是:父元件资料改变时,不会修改储存prop的子元件资料,只是以子元件资料为媒介,完成对prop的双向修改。
web前端面试怎么说
面试方法
-
程式码编写笔试
-
问答式
-
做过最满意的专案是什么?
-
专案背景
-
为什么要做这件事情?
-
最终达到什么效果?
-
你处于什么样的角色,起到了什么方面的作用?
-
在专案中遇到什么技术问题?具体是如何解决的?
-
如果再做这个专案,你会在哪些方面进行改善?
-
描述一个你遇到过的技术问题,你是如何解决的?
-
这个问题很常见,有没有遇到过很不常见的问题?比如在网上根本搜不到解决方法的?
-
是否有设计过通用的元件?
-
请设计一个 Dialog(弹出层) / Suggestion(自动完成) / Slider(图片轮播) 等元件
-
你会提供什么接口?
-
呼叫过程是怎样的?可能会遇到什么细节问题?
-
你最擅长的技术是什么?
-
你觉得你在这个技术上的水平到什么程度了?你觉得最高级别应该是怎样的?
-
浏览器及效能
-
这些优化方法背后的原理是什么?
-
除了这些常规的,你还了解什么最新的方法么?
-
(这个问既考察技术深度又考察技术广度,其实要答好是相当难的,注意越详细越好)
-
一个页面从输入 URL 到页面载入完的过程中都发生了什么事情?越详细越好
-
谈一下你所知道的页面效能优化方法?
-
如何分析页面效能?
-
其它
-
除了前端以外还了解什么其它技术么?
-
对计算机基础的了解情况,比如常见资料结构、编译原理等
-
最近在学什么?接下来半年你打算学习什么?
-
做什么方面的事情最让你有成就感?需求设计?规划?具体开发?
-
后续想做什么?3 年后你希望自己是什么水平?
-
在之前做过的专案中,有没有什么功能或改进点是由你提出来的?
-
是否有参与和改进其它开源专案
过程遵循 STAR 面试法 。
校招和社招的是不一样的,校招会更加关注基础知识,而社招会更加关注之前做过的专案情况。
专案相关
面试其实说白了就是根据一个人之前的经历,来判断出后续这人会做得怎样,如果你之前从没做成过一件事情,凭什么让别人相信你之后能做成呢?因此无论哪里的面试都会问你之前做过的专案
专案可以是多人协助开发一个产品,也可以是自己个人做过的业余应用,只需介绍 1、2 个就够了,需要注意的是 1 + 1 != 2,做了两个平庸的专案不如做了一个好专案。
一般来说会问如下几方面的问题:
技术相关 - 1 面
技术一面主要判断对基础知识的掌握
技术二面主要判断技术深度及广度
兴趣相关
主动性相关
页面前端面试经常问到的问题
其实,不管是什么样的面试形,问的问题都差不多,万变不离其宗,都有规律可寻。其实对所有的面试官而言,只有一个目的:在最短的时间里了解到你最多的资讯。想高效率的准备面试,先从这七个大方面着手吧!
一、基本情况
1、请用最简洁的语言描述您从前的工作经历和工作成果。
二、专业背景
您认为此工作岗位应当具备哪些素质?
三、工作模式
您平时习惯于单独工作还是团队工作?
四、价值取向
您对原来的单位和上司的看法如何?
五、资质特性
您如何描述自己的个性?
六、薪资待遇
是否方便告诉我您目前的待遇是多少?
七、背景调查
您是否介意我们通过您原来的单位迚行一些调查?
95%的面试基本上都离不开这些问题,当然还有可能问一些专业问题,我想如果你做过的话应该都不是什么难事,一般面试官都不会过多的问专业方面的问题的。以上资讯直接参考楚湘人才网面试宝典篇之化繁为简,把HR的上百道问题汇总成七大类和面试常问经典问题。更多更全面的面试资讯 面试技巧 面试问题请登陆楚湘人才网或关注微信公众平台:楚湘人才网
如何用ecshop修改页面前端布局
网站是在服务器上的庆,你朋友给你FTP或服务器的帐号密码没。如果没有的话要下,是在网站的档案目录里
web前端面试怎么介绍
- 你的笔试题, 根据其做延伸.
-
你的简历, 技术栈、工作外学习情况、专案经验. 第一页很重要, 最好都能掌握, 有亮点更好.
-
面试官额外的延展的知识点, 随机问,看你运气和积累(一般会提及到 ES6、解决实际问题的方法、资料结构与算法都有可能).
-
刷题, 各种基础题会帮你快速回忆起来, 比你看书快, 如果基础不好的话, 看书好好学学吧.
-
简历上自己写的东西, 要能说出来.
-
积累, 每次面试不成功就回来填坑吧, 还是有掌握不到位的. 我觉得能坚持下来的话, 找工作只是时间问题.
-
据公司业务不同, 着重点不一样, 公司能把你简历挑出来, 就说明有用人单位感兴趣的部分.
-
可能你写的是熟练使用 Vue, 公司也是这个技术栈.
-
可能你知识写的全面, 公司想面面你实际掌握怎么样.
-
可能你专案写的贴合用人单位需要, 比如都是做后台管理的.
-
封装过哪些元件?有自己写过 UI 元件吗?
-
什么是 MVVM , 和 MVC 是什么区别, 原理是什么?
-
父子元件怎么通讯的?
-
兄弟元件怎么通讯的?
-
生命周期有哪些, 怎么用?
-
Vue 全家桶都用过哪些?具体怎么用?
-
盒子模型
-
如何给未知宽高的图片垂直居中对齐? 有几种方法?
-
移动端的 rem 布局.
-
前端可以做哪些优化, 或问你 SEO, 基本都问.
-
清除浮动方式和原理, 基本都问. 几种方式? 原理? 为什么要用伪元素? 具体程式码怎么写,为什么这么写?
-
清除浮动就会涉及到 BFC 的问题.
-
给你实际页面例子, 让你口述布局或手写实现细节, 可以使用几种方法, 怎么写相容性好, 拓展性好.
-
具体 API 哪个 CSS 版本的?
-
CSS3 新增了哪些 API?
-
可能问你哪些 API 是 CSS 哪个版本的? 相容性怎么样.
-
CSS hack 是什么? 包含什么? 怎么处理相容性问题?
-
HTML5 新增了哪些 API? 哪些比较常用? 用来做什么? 实际怎么用?
-
cookie, session, localStrorage, sessionStorage 区别, 具体怎么用程式码去操作?
-
变数宣告提升的问题.
-
闭包的原理, 闭包的各种题, 基本都问.
-
DOM2 事件流, 冒泡和捕获问题?
-
this 指向问题, 一般都是在笔试题里, 拿着问你, 问的比较多.
-
call 和 apply 区别? 有的还会加问 bind?
-
面向物件程式设计中的继承问题, 原型链问题在笔试题里比较常见.
-
jQuery API , 各种操作 DOM 用法, 还有一些新的 API, 这种在不用 3 大框架的公司会问的很详细.
-
可能有些考算法结构的, 可以了解一下, 一般前端掌握的很少.
-
Ajax 基本都问, 问的细节可能不同, 比如 get 和 post 有什么区别?
-
阵列的方法 - es6 以下基本都能熟练使用, 应该会加分不少
-
字串的方法 - 拼接, 撷取, 带些正则
-
阵列去重问的挺多的(解法很多, ES6 有很多简短写法)
-
ES6 的 Promise , 很多都会问. 如果公司用框架或者你写了, 还会问你 Class.
-
var, let, const区别, 问的多.
-
栈和伫列结构, 有的会问.
-
跨域问题: 同源策略, 解决方案, 解决原理(比如 jsonp 的原理), 这里都是高发区.
应对
框架问题: (Vue 举例, 3框架实质问题差不多, 具体有些差异)
HTML5 + CSS3
JavaScript
网页前端布局都用什么工具
一般应该都是用ps或者类似的作图软体先把图画出来,然后再手写程式码。
用ps等做出软体是方便作图后修改,因为不管是内部用还是给客户总是要多修改的
㈡ 前端开发设计
1.用于UI设计的Sketch app
Sketch正在迅速取代Photoshop,用于从低保真线框到高保真模型和设计图标的所有的UI设计任务。
Sketch app是一个专为web和移动设计人员制作的Mac应用程序。它的功能,灵活性和速度满足了你对于一个轻量级,易于使用的软件包的想象。有了这个app,你就可以专注于创作最佳的设计了。
它提供了一个顺畅的工作环境,为任何界面提供工艺化的矢量元素,而且还有你想从Photoshop得到的许多功能,瞎芦如文本效果和图层样式。
如果Sketch能够继续提供最佳的UI设计体验,那么它在2016年及以后必然还会继续保持辉煌。
2.基于浏览器的IDE
桌面IDE已经存在了几十年,从Notepad到Xcode和visual Studio。IDE通过提供建议和语法高亮等功能使得我们可以卜燃更容易地编写代码。在IDE中写代码非常简单,而且很易于阅读。
但传统的IDE是作为桌面应用程序发布的。从过去的几年里,基于浏览器的云IDE发生了戏剧性的变化。除了web浏览器,我们不再需要任何软件,因为浏览器型神虚允许设备操作来自于任何有互联网接入的计算机的代码。
云IDE的功能更像是web应用程序,你可以保存代码到你的帐户进行共享或个人存储。CodePen是目前最流行的IDE,支持HTML/ CSS/JS,具备像Jade/Haml 和LESS/SCSS一样自定义的预处理。
CodePen主攻web前端。它可以显示你最近的创造,并从其他网络资源上得到反馈。为恼人的bug建立一个测试案例。你还可以从CodePen上为你的项目找到设计模式和灵感。
3.card layouts(卡片布局)
网站的卡片布局在几年前通过Pinterest而普及,从此成为了内容繁多网页的趋势。免费插件,如jQuery Masonry可用来模仿这种布局风格,它的动画卡片可适应不同的高度和宽度。
卡片布局最适合用在信息很多却又希望能被浏览的页面。Google Now就使用卡片布局来为它的app做广告。
你可以将卡片式布局看成是很多动态的网格,网格中只呈现最简明的重要内容,这些内容条目组合在一起就形成了基本的列表。在线杂志就是完美的例子,如UGSMAG和The Next Web,就使用了卡片布局来展示其最新懂得帖子和内容。
4.自定义的解说视频
形状各异的组织都趋向于自定义解说视频。使用动画,例如Crazy Egg来制作这些视频。即使如此,不同的视频依赖于真正的镜头,例如Instagram Direct。
解说视频的目的是说明产品或服务是如何工作的。访问者有可能在浏览了一系列功能之后,依然不知道如何操作这个产品。而可视化的视频则可以在短短几分钟的时间内一一说明功能,并涵盖所有重要的内容。最关键的是人们喜欢观看视频而不怎么喜欢阅读文章。他们可以很容易地从视频中明白你想表达什么。
如果你想自己尝试做一个自定义的解说视频,那么可以阅读Udemy课程。这是一个侧重登陆页面设计视频讲解的深入学习课程。Udemy课程不仅仅说明了如何使用动画视频软件,它也会告诉你如何使用视频来吸引和隐蔽访问者。
5.实况产品预览
登陆页面设计因网络速度的提高和浏览器功能的扩大,而发生了令人难以置信的改变。我注意到一个重要趋势是,就是主页或自定义登陆页面增加了实时产品预览。
以Slack的产品页面作为例子。一个视频演示和矢量图形覆盖了它的界面。这些产品预览是让潜在用户第一眼就知道产品是如何操作的。
不只是消息,所有的文件,图像,PDF文件,文档和电子表格都可以放到Slack,和你想要分享的任何人共享。你可以添加注释,标注星号供以后参考,这一切完全都是可以搜索的。
6.自动化任务运行器
前端开发的世界,随着一堆针对网站创新而出现的新的最佳实践,发生了巨大的改变。任务运行器/构建系统,例如Gulp和Grunt,替代了以前事先需要大量手动去完成的任务,越来越被我们广泛使用。
自动化是快速周转和高质量代码的命脉。众所周知,机器不会出错,所以自动化程度越高,产生的问题越少。
这些工具基本上运行的是JS代码,可以自动化实现部分工作流程——无论是自定义的JS代码还是其他人写的脚本。
7.用于设计的协作工具
即时消息和群聊已经出现了十多年。人们喜欢这个功能,并在今后他们可以继续使用此功能。然而,这些资源在传统上依赖于纯文本附加文件的一些功能。
但是,我们在讨论的是未来,未来一个新出现的趋势是,在聊天应用程序中共享实时设计文档。Notable就是其中一个例子,创新和注释可以被分层在文档的顶部。通过快速迭代它提供了更好的界面。从草图到完全编码的网页,Notable让团队在设计过程的每一步得到更快的反馈。
Slack是当下最流行的聊天应用程序,支持许多类似的功能。
8.响应式前端框架
前端框架,例如Bootstrap,已经存在了相当长的时间,并将继续展现其价值。响应式设计,受其成为框架方式的制约,可以成为前端代码,而不是仅仅只是后端(Django,Laravel,等等)。
迈入2016年,我认为我们会阅读到更多关于响应式前端框架以及它们在web项目中的价值的内容。并且在接下来的一年时间里,可能会发布很多前端框架的app,比现在的功能更强大。许多设备正在急切等待Foundation 6以及Bootstrap4公共V1版本的发布。
9.更关注UX设计
UX设计是通过改进可用性,可访问性,以及用户和产品之间互动产生的愉悦感来加强用户满意度的过程。
用户体验设计领域将随着更多设计师和开发者的关注而继续快速增长。UI设计是UX设计的一部分,但不是最终目标。UI是手段而不是目的,最终目的是提供一个梦幻般的用户体验。
目前,针对这些目的的资源有UX Stack Exchange和free UX ebooks。如果你还没有涉猎用户体验,那么现在是学习和了解UX原则如何应用到所有数字界面窗口的最佳时机。
10.支持触摸的网站功能
智能手机浏览器,支持所有站点的触摸功能,以保持reverse similarity。我们也可以看到更多的插件和自定义元素添至站点,关注触摸事件的特定对象。
我们希望网站可以实现触摸功能。而且这种网站也会因为其独特的功能而提升访问量。如Photoswipe和Dragend.js等内置的插件可以处理触摸屏上的滑动和点击手势。web开发人员不仅要会构建响应式网站,还得能构建具备触摸功能的网站。
这些插件提供了触摸功能,但是网站还需要具备其他的手势功能。如果你多搜索一下的话,你会发现一些真正令人印象深刻的,针对web的,内置的,纯粹依靠触摸事件的功能。
这些就是3.0时代的Web设计趋势,它们的到来和发展将使得构建网站变得更容易和更简单。
㈢ access相同课程只显示一次
当多个用户同时访问一个网站或应用程序时,可能会出现多次显示相同课程的情况。为了解决这个问题,可以采用以下几种方法:
1. 数据库去重
在数据库中,可以对课程名称和其他相关信息进行去重处理。这样,当多个用户访问同一课程时,系统只会显示一次。这种方法可以有效地减少数据冗余,提高系统运行效率。
2. 缓存机制
可以使用缓存机制来减少重复数据的显示。当用户访问一个页面时,系统会将相关数据存储在缓存中,以便下一次访问时可以直接从缓存中获取答卖数据,而不需要再次从服务器上获取。这样就可以有效地减少服务器负载,提高系统性能。
3. 全局变量
可以使用全局变量来薯游记录已经显示过的课程。当用户访问页面时,系统会检查全局变量中是否已经显示过该课程,如果已经显示过,就不会再次显示。这种方法适用于小型应用程序,因为全局变量可能会占用过多的内存空间。
4. 前端去重
在前端页面中,可以使用JavaScript等技术来对数据进行去重。当数据加载到页面上时,系统会检查是否已经显示过该课程,如果已经显示过,就不会再次显示。这种方法可以减少服务器负载,清手逗提高页面加载速度。
综上所述,通过数据库去重、缓存机制、全局变量和前端去重等方法,可以有效地解决多个用户同时访问同一课程时重复显示的问题。这些方法不仅可以提高系统性能,还可以提升用户体验。
㈣ 数组去重方法 js
js数组去重的方法可以利用数组排序,通过相邻元素比较,去除型世重复元素。
去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。在真实的项目中碰到的数组去重,一般都是后台去处理,很少让前端处理卜穗肢数组去重。虽然日常项目用到的概率比较低,但还是需要了解一下,以防面试的时候可能回被问到。
利用for嵌套for,然后splice去重(ES5中最常用)。双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。想快速学习更多常用的ES6语法,可以看一些相关的文章如《学习ES6笔记──工作中常用到的ES6语法》。
js数组去重的几种方法
利用数组排序,通过相邻元素比较,去除重复元素,可以严格匹配以区分数据类型。
借用对象属性方法,将数组中的元素添加为对象的属性。族慎遍历数组元素的时候查询对象是否已经有该属性,如果有则不重复添加。
借用正则匹配的方法,将新数组转换为字符串。原数组中的每个元素与在字符串中查找,如果匹配到,则不添加。
使用js新特性的Map对象,使用键值对的方式修改第二种方法。或者利用Set对象,自动过滤掉重复项,而且可以判断数据类型。
㈤ js怎么实现<select>下拉框去重
这个应该是从数据源里取出来, 然后插入到前端页面中的, 去重应该从它取数据的位置去操作, 这个要看项目使用什么框架写的
如果后台的代码不能修改, 那你可以用js在前台页面加载完以后进行去重
㈥ 前端数组排序
第一种:简单的sort排序
2.冒泡排序
3.选择排序
4.数组sort加splice截取去重(推荐)
5.数组splice截取方法去重
6.数组indexOf方法去重(推荐)
㈦ 前端算法详解——二分法(查找、排序、去重、最小值)
需求:针对一有序数组查找某一个姿纳数是否在该数组中。
分析与思路: 二分法,一分为二。将数组分为两个进行查找,若该数小于中间值,则向左查找,否则向右查找。然后递归再次查找(这样每一次都是排除掉一半的不可能)
需求:将无序数组进行排序。
分析与思路: 将原始数组一分为二个数组(left、right),再讲这两个数组利用递归再次进行拆分...最后再将左右两个数组进行排氏燃序。
分析与思路:歼册虚同理将数组一分为二,左右分别去重,在一起去重
㈧ 如何高效实现批量插入数据,并去重
c#,sqlserver。写一下我将前端获取到的缓存数据批量插入数据库的表。
在sqlserver数据库下,展开(可编程性)-->(类型)-->(用户自定义表类型)。建一个自定义表类型,表类型结构即是前端传过来的表格数据结构。例如:
CREATE TYPE [dbo].[DT_SAP_ASN] AS TABLE(
[GUID] [nvarchar](50) NULL,
[VBELN_SIP] [nvarchar](30) NULL,
[POSNR_SIP] [nvarchar](30) NULL
)
GO
然后再写个存储,用于调用此存储批量将前端传入的datatable缓存数据批量插入数据库的某个表。例如:
CREATE PROC [dbo].[SP_EDI_SAP_ASN]
(
@DT_SAP_ASN DT_SAP_ASN READONLY --输入参数,刚刚自定义的表类型
)
AS
BEGIN
SET NOCOUNT OFF
INSERT INTO dbo.EDI_ASN_Log
( ID ,
GUID ,
VBELN_SIP ,
POSNR_SIP ,
)
SELECT NEWID() ,
GUID ,
VBELN_SIP ,
POSNR_SIP
FROM @DT_SAP_ASN
SET NOCOUNT ON
END
当然,去重的话在inset那边select表#DT_SAP_ASN distinct一下即可
㈨ 前端常用的一些算法
/*去重*/
function delRepeat(arr){
var newArray=new Array();
var len=arr.length;
for(var i=0;i
for(var j=i+1;j
{
if(arr[i]==arr[j])
{
++i;
}
}
newArray.push(arr[i]);
}
return newArray;
}
var arr=new Array("red","red","1","5","2");
alert(delRepeat(arr));
/*二分法*/
又称为折半查找算法,但是有缺陷就是要求数字是预先排序好的
function binary(items,value){
var startIndex=0,
stopIndex=items.length-1,
midlleIndex=(startIndex+stopIndex)>>>1;
while(items[middleIndex]!=value && startIndex
if(items[middleIndex]>value){
stopIndex=middleIndex-1;
}else{
startIndex=middleIndex+1;
}
middleIndex=(startIndex+stopIndex)>>>1;
}
return items[middleIndex]!=value ? false:true;
}
/*十六进制颜色值的随机生成*/
function randomColor(){
var arrHex=["0","2","3","4","5","6","7","8","9","a","b","c","d"],
strHex="#",
index;
for(var i=0;i<6;i++){
index=Math.round(Math.random()*15);
strHex+=arrHex[index];
}
return strHex;
}
/*一个求字符串长度的方法*/
function GetBytes(str){
var len=str.length,
bytes=len;
for(var i=0;i
if(str.CharCodeAt>255){
bytes++;
}
}
return bytes;
}
/*插入排序*/
所谓的插入排序,就是将序列中的第一个元素看成一个有序的子序列,然后不段向后比较交换比较交换。
function insertSort(arr){
var key;
for(var j = 1; j < arr.length ; j++){
//排好序的
var i = j - 1;
key = arr[j];
while(i >= 0 && arr[i] > key){
arr[i + 1] = arr[i];
i --;
}
arr[i + 1] = key;
}
return arr;
}
/*希尔排序*/
希尔排序 ,也称 递减增量排序算法
其实说到底也是插入排序的变种
function shellSort(array){
var stepArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1]; // reverse()在维基上看到这个最优的步长较小数组
var i = 0;
var stepArrLength = stepArr.length;
var len = array.length;
var len2 = parseInt(len/2);
for(;i < stepArrLength; i++){
if(stepArr[i] > len2){
continue;
}
stepSort(stepArr[i]);
}
//排序一个步长
function stepSort(step){
//console.log(step)使用的步长统计
var i = 0, j = 0, f, tem, key;
var stepLen = len%step > 0 ? parseInt(len/step) + 1 : len/step;
for(;i < step; i++){//依次循环列
for(j=1;/*j < stepLen && */step * j + i < len; j++){//依次循环每列的每行
tem = f = step * j + i;
key = array[f];
while((tem-=step) >= 0){//依次向上查找
if(array[tem] > key){
array[tem+step] = array[tem];
}else{
break;
}
}
array[tem + step ] = key;
}
}
}
return array;
}
/*快速排序*/
快速排序算法就系对冒泡排序的一种改进,采用的就是算法理论中的分治递归的思想。
具体做法:通过一趟排序将待排序的纪录分割成两部分,其中一部分的纪录值比另外一部分的纪录值要小,就可以继续分别对这两部分纪录进行排序;不段的递归实施上面两个操作,从而实现纪录值的排序。
function sort(arr){
return quickSort(arr,0,arr.length-1);
function quickSort(arr,l,r){
if(l
var mid=arr[parseInt((l+r)/2)],i=l-1,j=r+1;
while(true){
//大的放到右边,小的放到左边, i与j均为游标
while(arr[++i]
while(arr[--j]>mid);
if(i>=j)break;//判断条件
var temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
quickSort(arr,l,i-1);
quickSort(arr,j+1,r);
}
return arr;
}
}
function main(){
var list=new Array(49,38,65,97,76,13,27);
document.write(sort(list).valueOf());
}
main();
/*冒泡法*/
function bullSort(array){
var temp;
for(var i=0;i
for(var j=array.length-1;j>i;j--){
if(array[j]
temp = array[j];
array[j]=array[j-1];
array[j-1]=temp;
}
}
}
return array;
}
/*js递归实现方案*/
递归函数是在一个函数通过调用自身的情况下去解决的:
方式如下:
function factorial(num){
if(num<=1){
return 1;
}else{
return num*factorial(num-1);
}
}
但是这在js里面可能会出现错误:
var anotherFactorial = factorial;
factorial=null;
alert(anoterFactorial(4));
因为在调用anoterFactorial时内部的factorial已经不存在了。
解决方法是通过arguments.callee来解决。
如下:
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));
成功!!!!
}
/**js模拟多线程**/
if (Array.prototype.shift==null)
Array.prototype.shift = function (){
var rs = this[0];
for (var i=1;i
this.length=this.length-1
return rs;
}
if (Array.prototype.push==null)
Array.prototype.push = function (){
for (var i=0;i
return this.length;
}
var commandList = [];
var nAction = 0;//控制每次运行多少个动作
var functionConstructor = function(){}.constructor;
function executeCommands(){
for (var i=0;i
if (commandList.length>0){
var command = commandList.shift();
if (command.constructor == functionConstructor)
if (command.scheleTime == null || new Date()-command.scheleTime>0)
command();
else
commandList.push(command);
}
}
function startNewTask(){
var resultTemp = document.getElementById("sampleResult").cloneNode(true);
with (resultTemp){
id="";style.display="block";style.color=(Math.floor(Math.random()* (1<<23)).toString(16)+"00000").substring(0,6);
}
document.body.insertBefore(resultTemp,document.body.lastChild);
commandList.push(function(){simThread(resultTemp,1);});
nAction++;
}
function simThread(temp,n){
if (temp.stop) n--;
else temp.innerHTML = temp.innerHTML - (-n);
if (n<1000)
commandList.push(function(){simThread(temp,++n)});
else{
var command = function(){document.body.removeChild(temp);;nAction--;};
command.scheleTime = new Date()-(-2000);
commandList.push(command);
}
}
window.onload = function(){setInterval("executeCommands()",1);}
/
/*选择法排序*/
选择法主要有三种:
《1》简单的选择排序:简单的前后交互。
/*简单选择法排序*/
其实基本的思想就是从待排序的数组中选择最小或者最大的,放在起始位置,然后从剩下的数组中选择最小或者最大的排在这公司数的后面。
function selectionSort(data)
{
var i, j, min, temp , count=data.length;
for(i = 0; i < count - 1; i++) {
/* find the minimum */
min = i;
for (j = i+1; j < count; j++)
{ if (data[j] < data[min])
{ min = j;}
}
/* swap data[i] and data[min] */
temp = data[i];
data[i] = data[min];
data[min] = temp;
}
return data;
}
《2》树型排序:又称锦标赛排序,首先对n个元素进行两两比较,然后在其中[n/2]个较小者再进行两两比较如此重复直至选出最小的关键字的纪录为止。(可用完全二差树表示)。缺点:辅助空间需求过大,和“最大值”进行多余比较
《3》堆排序:(不适用于纪录数较少的文件)
堆排序算法的过程如下:
1)得到当前序列的最小(大)的元素
2)把这个元素和最后一个元素进行交换,这样当前的最小(大)的元素就放在了序列的最后,而原先的最后一个元素放到了序列的最前面
3)的交换可能会破坏堆序列的性质(注意此时的序列是除去已经放在最后面的元素),因此需要对序列进行调整,使之满足于上面堆的性质.
重复上面的过程,直到序列调整完毕为止.
js实现:
/**
*堆排序
* @param items数组
* @return排序后的数组
*/
function heapSort(items)
{
items = array2heap(items); //将数组转化为堆
for(var i = items.length - 1; i >= 0; i--)
{
items = swap(items, 0, i); //将根和位置i的数据交换(用于将最大值放在最后面)
items = moveDown(items, 0, i - 1); //数据交换后恢复堆的属性
}
return items;
}
/**
*将数组转换为堆
* @param items数组
* @return堆
*/
function array2heap(items)
{
for(var i = Math.ceil(items.length / 2) - 1; i >= 0; i--)
{
items = moveDown(items, i, items.length - 1); //转换为堆属性
}
return items;
}
/**
*转换为堆
* @param items数组
* @param first第一个元素
* @param last最后一个元素
* @return堆
*/
function moveDown(items, first, last)
{
var largest = 2 * first + 1;
while(largest <= last)
{
if(largest < last && items[largest] < items[largest + 1])
{
largest++;
}
if(items[first] < items[largest])
{
items = swap(items, first, largest); //交换数据
first = largest; //往下移
largest = 2 * first + 1;
}
else
{
largest = last + 1; //跳出循环
}
}
return items;
}
/**
*交换数据
* @param items数组
* @param index1索引1
* @param index2索引2
* @return数据交换后的数组
*/
function swap(items, index1, index2)
{
var tmp = items[index1];
items[index1] = items[index2];
items[index2] = tmp;
return items;
}
var a = [345,44,6,454,10,154,3,12,11,4,78,9,0,47,88,9453,4,65,1,5];
document.write(heapSort(a));
所谓归并就是将两个或者两个以上的有序表合成一个新的有序表。
递归形式的算法在形式上较为简洁但实用性较差,与快速排序和堆排序相比,归并排序的最大特点是,它是一种稳定的排序方法。
js实现归并:
function MemeryArray(Arr,n, Brr, m)
{ var i, j, k;
var Crr=new Array();
i = j = k = 0;
while (i < n && j < m)
{
if (Arr[i] < Brr[j])
Crr[k++] = Arr[i++];
else
Crr[k++] = Brr[j++];
}
while (i < n)
Crr[k++] = Arr[i++];
while (j < m)
Crr[k++] = Brr[j++];
return Crr;
}
var Arr=new Array(45,36,89,75,65);
var Brr=new Array(48,76,59,49,25);
alert(MemeryArray(Arr , Arr.length , Brr , Brr.length));
归并排序待续,先睡了:
归并排序:
//将有二个有序数列a[first...mid]和a[mid...last]合并。
function mergearray(Arr,first,mid,last,tempArr)
{
var i = first, j = mid + 1;
var m = mid, n = last;
var k = 0;
while (i <= m && j <= n)
{
if (Arr[i] < Arr[j])
tempArr[k++] = Arr[i++];
else
tempArr[k++] = Arr[j++];
}
while (i <= m)
tempArr[k++] = Arr[i++];
while (j <= n)
tempArr[k++] = Arr[j++];
for (i = 0; i < k; i++)
Arr[first + i] = tempArr[i];
}
function mergesort(Arr,first,last)
{
var tempArr=new Array();
if (first < last)
{
var mid = (first + last)>>>1;
mergesort(Arr, first, mid, tempArr); //左边有序
mergesort(Arr, mid + 1, last, tempArr); //右边有序
mergearray(Arr, first, mid, last, tempArr); //再将二个有序数列合并
}
return Arr;
}
var Arr=new Array(1,65,45,98,56,78);
alert(mergesort(Arr,0,Arr.length-1));
/*比较两个字符串的相似性-Levenshtein算法简介*/
问题与描述:
近似字符串匹配问题
说明:设给定样本,对于任意文本串,样本P在文本T中的K-近似匹配(K-approximate match)是指P在T中包含最多K个差异的匹配,这里的差别指:
(1)修改:P与T中对应的字符不同
(2)删除:T中含有一个未出现在P中的字符
(3)插入:T中不包含出现在P中的一个字符
(也就是编辑距离问题)
例如:
T: a p r o x i o m a l l y
P: a p p r o x i m a t l y
经过1:插入2:删除3:修改
那么就是一个3-近似问题
事实上,两个字符串可能有不得出不同的差别数量,所以K-近似匹配要求:
(1)差别数最多为K个
(2)差别数为所有匹配方式下最少的称为编辑距离
(字符串T到P最少的差别数称为T和P的编辑距离)
试验要求:
(1)利用动态规划方法给出两个字符串编辑距离的算法
(2)分析复杂度
(3)考虑其它方法
Levenshtein Distance来文史特距离
goodzzp
LD也叫edit distance,它用来表示2个字符串的相似度,不同于Hamming Distance,它可以用来比较2个长度不同的字符串。LD定义为需要最少多少步基本操作才能让2个字符串相等,基本操作包含3个:
1,插入;
2,删除;
3,替换;
比如,kiteen和sitting之间的距离可以这么计算:
1,kitten – > sitten,替换k为s;
2,sitten – > sittin,替换e为i;
3,sittin – > sitting,增加g;
所以,其LD为3;
计算LD的算法表示为:
int LevenshteinDistance(char str1[1..lenStr1], char str2[1..lenStr2])
// d is a table with lenStr1+1 rows and lenStr2+1 columns
declare int d[0..lenStr1, 0..lenStr2]
// i and j are used to iterate over str1 and str2
declare int i, j, cost
for i from 0 to lenStr1
d[i, 0] := i
for j from 0 to lenStr2
d[0, j] := j
for i from 1 to lenStr1
for j from 1 to lenStr2
if str1[i] = str2[j] then cost := 0
else cost := 1
d[i, j] := minimum(
d[i-1, j ] + 1,// deletion
d[i , j-1] + 1,// insertion
d[i-1, j-1] + cost// substitution
)
return d[lenStr1, lenStr2];
这个算法其实就是一个矩阵的计算:
k i t t e n
0 1 2 3 4 5 6
s 1 1 2 3 4 5 6
i 2 2 1 2 3 4 5
t 3 3 2 1 2 3 4
t 4 4 3 2 1 2 3
i 5 5 4 3 2 2 3
n 6 6 5 4 3 3 2
g 7 7 6 5 4 4 3
首先给定第一行和第一列,然后,每个值d[i,j]这样计算:d[i,j] = min(d[i-1,j]+ 1,d[i,j-1] +1,d[i-1,j-1]+(str1[i] == str2[j]?0:1));
最后一行,最后一列的那个值就是LD的结果。
LD(str1,str2) <= max(str1.len,str2.len);
有人提出了Levenshtein automaton(Levenshtein自动机)来计算和某个字符串距离小于某个值的集合。这样能够加快近似字符串的计算过程。见文献:Klaus U. Schulz, Stoyan Mihov, Fast String Correction with Levenshtein-Automata. International Journal of Document Analysis and Recognition, 5(1):67--85, 2002.
A Guided Tour to Approximate String Matching GONZALONAVARRO
这篇文章里面对这个方面(字符串相似)进行了很多描述。其中,包含了动态规划法计算Edit distance的方法。
js实现:
//求两个字符串的相似度,返回差别字符数,Levenshtein Distance算法实现
function Levenshtein_Distance(s,t){
var n=s.length;// length of s
var m=t.length;// length of t
var d=[];// matrix
var i;// iterates through s
var j;// iterates through t
var s_i;// ith character of s
var t_j;// jth character of t
var cost;// cost
// Step 1
if (n == 0) return m;
if (m == 0) return n;
// Step 2
for (i = 0; i <= n; i++) {
d[i]=[];
d[i][0] = i;
}
for (j = 0; j <= m; j++) {
d[0][j] = j;
}
// Step 3
for (i = 1; i <= n; i++) {
s_i = s.charAt (i - 1);
// Step 4
for (j = 1; j <= m; j++) {
t_j = t.charAt (j - 1);
// Step 5
if (s_i == t_j) {
cost = 0;
}else{
cost = 1;
}
// Step 6
d[i][j] = Minimum (d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
}
}
// Step 7
return d[n][m];
}
//求两个字符串的相似度,返回相似度百分比
function Levenshtein_Distance_Percent(s,t){
var l=s.length>t.length?s.length:t.length;
var d=Levenshtein_Distance(s,t);
return (1-d/l).toFixed(4);
}
//求三个数字中的最小值
function Minimum(a,b,c){
return a
}
var str1="ddsddf",str2="xdsfsx";
alert(Levenshtein_Distance_Percent(str1,str2));
㈩ Web前端工程师应该知道的JavaScript使用小技巧
今天小编要跟大家分享的文章是关于Web前端工程师应该知道的JavaScript使用小技巧。任何一门技术在实际中都会有一些属于自己的小技巧。同样的,在使用JavaScript时也有一些自己的小技巧,只不过很多时候有可能容易被大家忽略。而在互联网上,时不时的有很多同行朋友会总结(或收集)一些这方面的小技巧。
今天在这篇文章中,小编会整理一些大家熟悉或不熟悉的有关于JavaScript的小技巧,希望能够对大家的学习和工作有所帮助。
一、数组
先来看使用数组中常用的一些小技巧。
01、数组去重
ES6提供了几种简洁的数组去重的方法,但该方法并不适合处理非基本类型的数组。对于基本类型的数组去重,可以使用...new
Set()来过滤掉数组中重复的值,创建一个只有唯一值的新数组。constarray=[1,1,2,3,5,5,1]
constuniqueArray=[...newSet(array)];
console.log(uniqueArray);
>Result:(4)[1,2,3,5]
这是ES6中的新特性,在ES6之前,要实现同样的效果,我们需要使用更多的代码。该技巧适用于包含基本类型的数组:undefined、null、boolean、string和number。如果数组中包含了一个object,function或其他数组,那就需要使用另一种方法。
除了上面的方法之外,还可以使用Array.from(newSet())来实现:constarray=[1,1,2,3,5,5,1]
Array.from(newSet(array))
>Result:(4)[1,2,3,5]
另外,还可以使用Array的.filter及indexOf()来实现:
constarray=[1,1,2,3,5,5,1]
array.filter((arr,index)=>array.indexOf(arr)===index)
>Result:(4)[1,2,3,5]
注意,indexOf()方法将返回数组中第一个出现的数组项。这就是为什么我们可以在每次迭代中将indexOf()方法返回的索引与当索索引进行比较,以确定当前项是否重复。
02、确保数组的长度
在处理网格结构时,如果原始数据每行的长度不相等,就需要重新创建该数据。为轿并了确保每行的数据长度相等,可以使用Array.fill来处理:letarray=Array(5).fill('');
console.log(array);
>Result:(5)["","","","",""]
03、数组映射
不使用Array.map来映射数组值的方法。constarray=[
{
ame:'大漠',
email:'w3cplus@#'
},
{
ame:'Airen',
email:'airen@#'
}
]
constname=Array.from(array,({name})=>name)
>Result:(2)["大漠","Airen"]
04、数组截断
如果你想从数组末尾删除值(删除数组中的最后一项),有比使用饥冲splice()更快的替代方法。
例如,你知道原始数组的大小,可以重新定义数组的length属性的值,就可以实现从数组末尾删除值:
letarray=[0,1,2,3,4,5,6,7,8,9]
console.log(array.length)
>Result:10
array.length=4
console.log(array)
>Result:(4)[0,1,2,3]
这是一个特别简洁的解决方案。但是,slice()方法运行更闭肢迹快,性能更好:
letarray=[0,1,2,3,4,5,6,7,8,9];
array=array.slice(0,4);
console.log(array);
>Result:[0,1,2,3]
05、过滤掉数组中的falsy值
如果你想过滤数组中的falsy值,比如0、undefined、null、false,那么可以通过map和filter方法实现:
constarray=[0,1,Ɔ',Ƈ','大漠','#',undefined,true,false,null,'undefined','null',NaN,'NaN',Ƈ'+0]
array.map(item=>{
returnitem
}).filter(Boolean)
>Result:(10)[1,"0","1","大漠","#",true,"undefined","null","NaN","10"]
06、获取数组的最后一项
数组的slice()取值为正值时,从数组的开始处截取数组的项,如果取值为负整数时,可以从数组末属开始获取数组项。
letarray=[1,2,3,4,5,6,7]
constfirstArrayVal=array.slice(0,1)
>Result:[1]
constlastArrayVal=array.slice(-1)
>Result:[7]
console.log(array.slice(1))
>Result:(6)[2,3,4,5,6,7]
console.log(array.slice(array.length))
>Result:[]
正如上面示例所示,使用array.slice(-1)获取数组的最后一项,除此之外还可以使用下面的方式来获取数组的最后一项:
console.log(array.slice(array.length-1))
>Result:[7]
07、过滤并排序字符串行表
你可能有一个很多名字组成的列表,需要过滤掉重复的名字并按字母表将其排序。
在我们的例子里准备用不同版本语言的JavaScript
保留字的列表,但是你能发现,有很多重复的关键字而且它们并没有按字母表顺序排列。所以这是一个完美的字符串行表(数组)来测试我们的JavaScript小知识。
varkeywords=['do','if','in','for','new','try','var','case','else','enum','null','this','true','void','with','break','catch','class','const','false','super','throw','while','delete','export','import','return','switch','typeof','default','extends','finally','continue','debugger','function','do','if','in','for','int','new','try','var','byte','case','char','else','enum','goto','long','null','this','true','void','with','break','catch','class','const','false','final','float','short','super','throw','while','delete','double','export','import','native','public','return','static','switch','throws','typeof','boolean','default','extends','finally','package','private','abstract','continue','debugger','function','volatile','interface','protected','transient','implements','instanceof','synchronized','do','if','in','for','let','new','try','var','case','else','enum','eval','null','this','true','void','with','break','catch','class','const','false','super','throw','while','yield','delete','export','import','public','return','static','switch','typeof','default','extends','finally','package','private','continue','debugger','function','arguments','interface','protected','implements','instanceof','do','if','in','for','let','new','try','var','case','else','enum','eval','null','this','true','void','with','await','break','catch','class','const','false','super','throw','while','yield','delete','export','import','public','return','static','switch','typeof','default','extends','finally','package','private','continue','debugger','function','arguments','interface','protected','implements','instanceof'];
因为我们不想改变我们的原始列表,所以我们准备用高阶函数叫做filter,它将基于我们传递的回调方法返回一个新的过滤后的数组。回调方法将比较当前关键字在原始列表里的索引和新列表中的索引,仅当索引匹配时将当前关键字push到新数组。
最后我们准备使用sort方法排序过滤后的列表,sort只接受一个比较方法作为参数,并返回按字母表排序后的列表。
在ES6下使用箭头函数看起来更简单:
=keywords
.filter((keyword,index)=>keywords.lastIndexOf(keyword)===index)
.sort((a,b)=>a
这是最后过滤和排序后的JavaScript保留字列表:
console.log(filteredAndSortedKeywords);
>Result:['abstract','arguments','await','boolean','break','byte','case','catch','char','class','const','continue','debugger','default','delete','do','double','else','enum','eval','export','extends','false','final','finally','float','for','function','goto','if','implements','import','in','instanceof','int','interface','let','long','native','new','null','package','private','protected','public','return','short','static','super','switch','synchronized','this','throw','throws','transient','true','try','typeof','var','void','volatile','while','with','yield']
08、清空数组
如果你定义了一个数组,然后你想清空它。通常,你会这样做:
letarray=[1,2,3,4];
functionemptyArray(){
array=[];
}
emptyArray();
但是,这有一个效率更高的方法来清空数组。你可以这样写:
letarray=[1,2,3,4];
functionemptyArray(){
array.length=0;
}
emptyArray();
09、拍平多维数组
使用...运算符,将多维数组拍平:
10、从数组中获取最大值和最小值
可以使用Math.max和Math.min取出数组中的最大小值和最小值:
constnumbers=[15,80,-9,90,-99]
constmaxInNumbers=Math.max.apply(Math,numbers)
constminInNumbers=Math.min.apply(Math,numbers)
console.log(maxInNumbers)
>Result:90
console.log(minInNumbers)
>Result:-99
另外还可以使用ES6的...运算符来完成:
constnumbers=[1,2,3,4];
Math.max(...numbers)
>Result:4
Math.min(...numbers)
>>Result:1
二、对象
在操作对象时也有一些小技巧。
01、使用...运算符合并对象或数组中的对象
同样使用ES的...运算符可以替代人工操作,合并对象或者合并数组中的对象。
//合并对象
constobj1={
ame:'大漠',
url:'#'
}
constobj2={
ame:'airen',
age:30
}
constmergingObj={...obj1,...obj2}
>Result:{name:"airen",url:"#",age:30}
//合并数组中的对象
constarray=[
{
ame:'大漠',
email:'w3cplus@#'
},
{
ame:'Airen',
email:'airen@#'
}
]
constresult=array.rece((accumulator,item)=>{
return{
...accumulator,
[item.name]:item.email
}
},{})
>Result:{大漠:"w3cplus@#",Airen:"airen@#"}
02、有条件的添加对象属性
不再需要根据一个条件创建两个不同的对象,以使它具有特定的属性。为此,使用...操作符是最简单的。
constgetUser=(emailIncluded)=>{
return{
ame:'大漠',
blog:'w3cplus',
...emailIncluded&&{email:'w3cplus@#'}
}
}
constuser=getUser(true)
console.log(user)
>Result:{name:"大漠",blog:"w3cplus",email:"w3cplus@#"}
constuserWithoutEmail=getUser(false)
console.log(userWithoutEmail)
>Result:{name:"大漠",blog:"w3cplus"}
03、解构原始数据
你可以在使用数据的时候,把所有数据都放在一个对象中。同时想在这个数据对象中获取自己想要的数据。
在这里可以使用ES6的Destructuring特性来实现。比如你想把下面这个obj中的数据分成两个部分:
constobj={
ame:'大漠',
blog:'w3cplus',
email:'w3cplus@#',
joined:-06-19',
followers:45
}
letuser={},userDetails={}
({name:user.name,email:user.email,...userDetails}=obj)
>{name:"大漠",blog:"w3cplus",email:"w3cplus@#",joined:"2019-06-19",followers:45}
console.log(user)
>Result:{name:"大漠",email:"w3cplus@#"}
console.log(userDetails)
>Result:{blog:"w3cplus",joined:"2019-06-19",followers:45}
04、动态更改对象的key
在过去,我们首先必须声明一个对象,然后在需要动态属性名的情况下分配一个属性。在以前,这是不可能以声明的方式实现的。不过在ES6中,我们可以实现:
constdynamicKey='email'
letobj={
ame:'大漠',
blog:'w3cplus',
[dynamicKey]:'w3cplus@#'
}
console.log(obj)
>Result:{name:"大漠",blog:"w3cplus",email:"w3cplus@#"}
05、判断对象的数据类型
使用Object.prototype.toString配合闭包来实现对象数据类型的判断:
constisType=type=>target=>`[object${type}]`===Object.prototype.toString.call(target)
constisArray=isType('Array')([1,2,3])
console.log(isArray)
>Result:true
上面的代码相当于:
functionisType(type){
returnfunction(target){
return`[object${type}]`===Object.prototype.toString.call(target)
}
}
isType('Array')([1,2,3])
>Result:true
或者:
constisType=type=>target=>`[object${type}]`===Object.prototype.toString.call(target)
constisString=isType('String')
constres=isString((Ƈ'))
console.log(res)
>Result:true
06、检查某对象是否有某属性
当你需要检查某属性是否存在于一个对象,你可能会这样做:
varobj={
ame:'大漠'
}
if(obj.name){
console.l