• 关于

    直到型结构是什么

    的搜索结果

问题

线性表 7月8日 【今日算法】

游客ih62co2qqq5ww 2020-07-09 07:47:37 504 浏览量 回答数 1

问题

不搞清这8大算法思想,刷再多题效果也不好的 7月23日 【今日算法】

游客ih62co2qqq5ww 2020-07-29 11:10:09 3 浏览量 回答数 1

问题

【精品问答】python技术1000问(1)

问问小秘 2019-12-01 21:57:48 456417 浏览量 回答数 22

阿里云试用中心,为您提供0门槛上云实践机会!

0元试用32+款产品,最高免费12个月!拨打95187-1,咨询专业上云建议!

回答

为什么你的代码是一个单体? 除了已经实现了微前端的应用之外,所有前端应用本质上都是单一的应用。原因是如果您正在使用 React 库进行开发,并且如果您有两个团队,则两个团队都应该使用相同的React 库,并且两个团队应该在部署时保持同步,并且在代码合并期间始终会发生冲突。它们没有完全分离,很可能它们维护着相同的仓库并具有相同的构建系统。单体应用的退出被标志为微服务的出现。但是它适用于后端! 什么是微服务? 对于微服务,一般而言最简单的解释是,它是一种开发技术,允许开发人员为平台的不同部分进行独立部署,而不会损害其他部分。独立部署的能力允许他们构建孤立或松散耦合的服务。为了使这个体系结构更稳定,有一些规则要遵循,可以总结如下:每个服务应该只有一个任务,它应该很小。所以负责这项服务的团队应该很小。关于团队和项目的规模,James Lewis 和 Martin Fowler 在互联网上做出的最酷解释之一如下: 在我们与微服务从业者的对话中,我们看到了一系列服务规模。报道的最大规模遵循亚马逊关于Two Pizza Team的概念(即整个团队可以由两个比萨饼供给),意味着不超过十几个人。在规模较小的规模上,我们已经看到了一个由六人组成的团队支持六项服务的设置。 我画了一个简单的草图,为整体和微服务提供了直观的解释: 从上图可以理解,微服务中的每个服务都是一个独立的应用,除了UI。UI仍然是一体的!当一个团队处理所有服务并且公司正在扩展时,前端团队将开始苦苦挣扎并且无法跟上它,这是这种架构的瓶颈。 除了瓶颈之外,这种架构也会导致一些组织问题。假设公司正在发展并将采用需要 跨职能 小团队的敏捷开发方法。在这个常见的例子中,产品所有者自然会开始将故事定义为前端和后端任务,而 跨职能 团队将永远不会成为真正的 跨职能 部门。这将是一个浅薄的泡沫,看起来像一个敏捷的团队,但它将在内部分开。关于管理这种团队的更多信息将是一项非常重要的工作。在每个计划中,如果有足够的前端任务或者sprint中有足够的后端任务,则会有一个问题。为了解决这里描述的所有问题和许多其他问题,几年前出现了微前端的想法并且开始迅速普及。 解决微服务中的瓶颈问题:Micro Frontends 解决方案实际上非常明显,采用了多年来为后端服务工作的相同原则:将前端整体划分为小的UI片段。但UI与服务并不十分相似,它是最终用户与产品之间的接口,应该是一致且无缝的。更重要的是,在单页面应用时代,整个应用在客户端的浏览器上运行。它们不再是简单的HTML文件,相反,它们是复杂的软件,达到了非常复杂的水平。现在我觉得微型前端的定义是必要的: Micro Frontends背后的想法是将网站或Web应用视为独立团队拥有的功能组合。每个团队都有一个独特的业务或任务领域,做他们关注和专注的事情。团队是跨职能的,从数据库到用户界面开发端到端的功能。(micro-frontends.org) 根据我迄今为止的经验,对于许多公司来说,直接采用上面提出的架构真的很难。许多其他人都有巨大的遗留负担,这使他们无法迁移到新的架构。出于这个原因,更柔软的中间解决方案更加灵活,易于采用和安全迁移至关重要。在更详细地概述了体系结构后,我将尝试提供一些体系结构的洞察,该体系结构确认了上述提议并允许更灵活的方式。在深入了解细节之前,我需要建立一些术语。 整体结构和一些术语 让我们假设我们通过业务功能垂直划分整体应用结构。我们最终会得到几个较小的应用,它们与单体应用具有相同的结构。但是如果我们在所有这些小型单体应用之上添加一个特殊应用,用户将与这个新应用进行通信,它将把每个小应用的旧单体UI组合成一个。这个新图层可以命名为拼接图层,因为它从每个微服务中获取生成的UI部件,并为最终用户组合成一个无缝 UI,这将是微前端的最直接实现朗 为了更好地理解,我将每个小型单体应用称为微应用,因为它们都是独立的应用,而不仅仅是微服务,它们都有UI部件,每个都代表端到端的业务功能。 众所周知,今天的前端生态系统功能多样,而且非常复杂。因此,当实现真正的产品时,这种直接的解决方案还不够。 要解决的问题 虽然这篇文章只是一个想法,但我开始使用Reddit讨论这个想法。感谢社区和他们的回复,我可以列出一些需要解决的问题,我将尝试逐一描述。 当我们拥有一个完全独立的独立微应用时,如何创建无缝且一致的UI体验? 好吧,这个问题没有灵丹妙药的答案,但其中一个想法是创建一个共享的UI库,它也是一个独立的微应用。通过这种方式,所有其他微应用将依赖于共享的UI库微应用。在这种情况下,我们刚刚创建了一个共享依赖项, 我们就杀死了独立微应用的想法。 另一个想法是在根级共享CSS自定义变量( CSS custom variables )。此解决方案的优势在于应用之间的全局可配置主题。 或者我们可以简单地在应用团队之间共享一些SASS变量和混合。这种方法的缺点是UI元素的重复实现,并且应该对所有微应用始终检查和验证类似元素的设计的完整性。 我们如何确保一个团队不会覆盖另一个团队编写的CSS? 一种解决方案是通过CSS选择器名称进行CSS定义,这些名称由微应用名称精心选择。通过将该范围任务放在拼接层上将减少开发开销,但会增加拼接层的责任。 另一种解决方案可以是强制每个微应用成为自定义Web组件(custom web component)。这个解决方案的优点是浏览器完成了范围设计,但需要付出代价:使用shadow DOM进行服务器端渲染几乎是不可能的。此外,自定义元素没有100%的浏览器支持,特别是IE。 我们应该如何在微应用之间共享全局信息? 这个问题指出了关于这个主题的最关注的问题之一,但解决方案非常简单:HTML 5具有相当强大的功能,大多数前端开发人员都不知道。例如,自定义事件(custom events) 就是其中之一,它是在微应用中共享信息的解决方案。 或者,任何共享的pub-sub实现或T39可观察的实现都可以实现。如果我们想要一个更复杂的全局状态处理程序,我们可以实现共享的微型Redux,通过这种方式我们可以实现更多的相应式架构。 如果所有微应用都是独立应用,我们如何进行客户端路由? 这个问题取决于设计的每个实现, 所有主要的现代框架都通过使用浏览器历史状态在客户端提供强大的路由机制, 问题在于哪个应用负责路由以及何时。 我目前的实用方法是创建一个共享客户端路由器,它只负责顶级路由,其余路由器属于相应的微应用。假设我们有 /content/:id 路由定义。共享路由器将解析 /content,已解析的路由将传递到ContentMicroApp。ContentMicroApp是一个独立的服务器,它将仅使用 /:id 进行调用。 我们必须是服务器端渲染,但是有可能使用微前端吗? 服务器端呈现是一个棘手的问题。如果你正在考虑iframes缝合微应用然后忘记服务器端渲染。同样,拼接任务的Web组件也不比iframe强大。但是,如果每个微应用能够在服务器端呈现其内容,那么拼接层将仅负责连接服务器端的HTML片段。 与传统环境集成至关重要!但是怎么样? 为了整合遗留系统,我想描述我自己的策略,我称之为“ 渐进式入侵 ”。 首先,我们必须实现拼接层,它应该具有透明代理的功能。然后我们可以通过声明一个通配符路径将遗留系统定义为微应用:LegacyMicroApp 。因此,所有流量都将到达拼接层,并将透明地代理到旧系统,因为我们还没有任何其他微应用。 下一步将是我们的 第一次逐步入侵 :我们将从LegacyMicroApp中删除主要导航并用依赖项替换它。这种依赖关系将是一个使用闪亮的新技术实现的微应用:NavigationMicroApp 。 现在,拼接层将每个路径解析为 Legacy Micro App ,它将依赖关系解析为 Navigation MicroApp ,并通过连接这两个来为它们提供服务。 然后通过主导航遵循相同的模式来为引导下一步。 然后我们将继续从Legacy MicroApp中获取逐步重复以上操作,直到没有任何遗漏。 如何编排客户端,这样我们每次都不需要重新加载页面? 拼接层解决了服务器端的问题,但没有解决客户端问题。在客户端,在将已粘贴的片段作为无缝HTML加载后,我们不需要每次在URL更改时加载所有部分。因此,我们必须有一些异步加载片段的机制。但问题是,这些片段可能有一些依赖关系,这些依赖关系需要在客户端解决。这意味着微前端解决方案应提供加载微应用的机制,以及依赖注入的一些机制。 根据上述问题和可能的解决方案,我可以总结以下主题下的所有内容: 客户端 编排路由隔离微应用应用之间通信微应用UI之间的一致性 服务端 服务端渲染路由依赖管理 灵活、强大而简单的架构 所以,这篇文章还是很值得期待的!微前端架构的基本要素和要求终于显现! 在这些要求和关注的指导下,我开始开发一种名为microfe的解决方案。在这里,我将通过抽象的方式强调其主要组件来描述该项目的架构目标。 它很容易从客户端开始,它有三个独立的主干结构:AppsManager, Loader, Router 和一个额外的MicroAppStore。 AppsManager AppsManager 是客户端微应用编排的核心。AppsManager的主要功能是创建依赖关系树。当解决了微应用的所有依赖关系时,它会实例化微应用。 Loader 客户端微应用编排的另一个重要部分是Loader。加载器的责任是从服务器端获取未解析的微应用。 Router 为了解决客户端路由问题,我将 Router 引入了 microfe。与常见的客户端路由器不同,microf 的功能有限,它不解析页面而是微应用。假设我们有一个URL /content/detail/13 和一个ContentMicroApp。在这种情况下,microfe 将URL解析为 /content/,它将调用ContentMicroApp /detail/13 URL部分。 MicroAppStore 为了解决微应用到微应用客户端的通信,我将MicroAppStore引入了 microfe。它具有与Redux库类似的功能,区别在于:它对异步数据结构更改和reducer 声明更灵活。 服务器端部分在实现上可能稍微复杂一些,但结构更简单。它只包含两个主要部分 StitchingServer 和许多MicroAppServer。 MicroAppServer MicroAppServer 的最小功能可以概括为 init 和 serve。 虽然 MicroAppServer 首先启动它应该做的是使用 微应用声明 调用 SticthingServer 注册端点,该声明定义了 MicroAppServer 的微应用 依赖关系, 类型 和 URL架构。我认为没有必要提及服务功能,因为没有什么特别之处。 StitchingServer StitchingServer 为 MicroAppServers 提供注册端点。当 MicroAppServer 将自己注册到 StichingServer 时,StichingServer 会记录MicroAppServer 的声明。 稍后,StitchingServer 使用声明从请求的URL解析 MicroAppServers。 解析M icroAppServer 及其所有依赖项后,CSS,JS和HTML中的所有相对路径都将以相关的 MicroAppServer 公共URL为前缀。另外一步是为CSS选择器添加一个唯一的 MicroAppServer 标识符,以防止客户端的微应用之间发生冲突。 然后 StitchingServer 的主要职责就是:从所有收集的部分组成并返回一个无缝的HTML页面。 其他实现一览 甚至在2016年被称为微前端之前,许多大公司都试图通过 BigPipe 来解决Facebook等类似问题。如今这个想法正在获得验证。不同规模的公司对该主题感兴趣并投入时间和金钱。例如,Zalando开源了其名为Project Mosaic的解决方案。我可以说,微型和 Project Mosaic.遵循类似的方法,但有一些重要的区别。虽然microfe采用完全分散的路由定义来增强每个微应用的独立性,但Project Mosaic更喜欢每条路径的集中路由定义和布局定义。通过这种方式,Project Mosaic可以实现轻松的A/B测试和动态布局生成。 对于该主题还有一些其他方法,例如使用iframe作为拼接层,这显然不是在服务器端而是在客户端。这是一个非常简单的解决方案,不需要太多的服务器结构和DevOps参与。这项工作只能由前端团队完成,因此可以减轻公司的组织负担,同时降低成本。 已经有一个框架叫做 single-spa。该项目依赖于每个应用的命名约定来解析和加载微应用。容易掌握想法并遵循模式。因此,在您自己的本地环境中尝试该想法可能是一个很好的初步介绍。但是项目的缺点是你必须以特定的方式构建每个微应用,以便他们可以很好地使用框架。 最后的想法 我相信微前端话题会更频繁地讨论。如果该主题能够引起越来越多公司的关注,它将成为大型团队的事实发展方式。在不久的将来,任何前端开发人员都可以在这个架构上掌握一些见解和经验,这真的很有用。 关于本文 译者:@Vincent.W 译文:https://zhuanlan.zhihu.com/p/82965940 作者:@onerzafer 原文:https://hackernoon.com/understanding-micro-frontends-b1c11585a297 加入阿里云钉钉群享福利:每周技术直播,定期群内有奖活动、大咖问答 阿里云开发者社区

茶什i 2020-01-06 17:57:24 0 浏览量 回答数 0

回答

链表啊,结构体里放一个char来记录字母,一个int来计数,遍历字符串后排序输出。 ######谢谢额 我猜自己发现了错误,又改写了一下,现在已经成功了。######我尝试去这样做了,但是结果还是出错。有思路,但是还是比较复杂,代码写出来了出错。也不知道是哪里有问题.######有人能帮帮忙吗?######定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了######回复 @水晶之夜 : 输出的时候类型强制转换下,(char)c[0][0]。估计用指针数组也行,或者也可以用typedef定义一个struct,但这些具体怎么写语句我也不会,没怎么好好用过C,反正大体上应该是这么个意思。######这里有一个问题,你定义的数组是整形的还是字符型?你不可能一个放字符,一个放次数,它们是不同的数据类型。######Hash Table完美解决 ######什么是Hash Table?###### 引用来自“猎户座”的答案 链表啊,结构体里放一个char来记录字母,一个int来计数,遍历字符串后排序输出。 我自己又重新调试了一下,把代码稍稍改了一下。现在基本上可以了。 #define N 1024 void f12() { //输入一串字符以?结束 char str[N]; gets(str); //全部字母小写化 int i; for(i=0;str[i]!='\0';i++) { str[i]=tolower(str[i]); } //定义一个结构体来记录字符和次数 Info a[26]; for(i=0;i<26;i++) { a[i].letter=i+97; a[i].count=0; } //统计字符 for(i=0;str[i]!='\0';i++) { if(str[i]>='a'&&str[i]<='z') { a[str[i]-'a'].count++; } } //排序 int j; for(i=0;i<26;i++) { int k=i; for(j=0;j<25;j++) { if(a[j].count<a[j+1].count) { //交换 int t=a[j].count; a[j].count=a[j+1].count; a[j+1].count=t; char c = a[j].letter; a[j].letter=a[j+1].letter; a[j+1].letter=c; } } } //输出 for(i=0;i<26;i++) { if(a[i].count==0) continue; printf("%c %d\n",a[i].letter,a[i].count); } } ###### 引用来自“NealFeng”的答案 定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了 哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接 int alpha[26]; void init_alpha(void){ int i; for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0; } #define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0) void set_alpha(char a){ _CHK_SET(a ,'A','Z'); _CHK_SET(a,'a','z'); } int max_num(void){ int re = alpha[0]; int i; for (i = 1 ; i< 26 ; i++) { if (alpha[i] > re) re = alpha[i]; } return re; } int print_max(void){ int i; int flag = 0; i = max_num(); if (alpha[i] == 0){ return 0; } printf(....); alpha[i] = 0; return 1; } 余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0. 哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。 ######有一点挺有意思的,确实,要求是打印出来,干嘛排序呢?###### 引用来自“中山野鬼”的答案 引用来自“NealFeng”的答案 定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了 哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接 int alpha[26]; void init_alpha(void){ int i; for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0; } #define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0) void set_alpha(char a){ _CHK_SET(a ,'A','Z'); _CHK_SET(a,'a','z'); } int max_num(void){ int re = alpha[0]; int i; for (i = 1 ; i< 26 ; i++) { if (alpha[i] > re) re = alpha[i]; } return re; } int print_max(void){ int i; int flag = 0; i = max_num(); if (alpha[i] == 0){ return 0; } printf(....); alpha[i] = 0; return 1; } 余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0. 哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。 我测试了你一下你这个代码,还有5个错误。不太理解。。 --------------------Configuration: temp - Win32 Debug-------------------- Compiling... temp.cpp d:\my files\c program\wow\temp\temp.cpp(25) : error C2062: type 'int' unexpected d:\my files\c program\wow\temp\temp.cpp(26) : error C2143: syntax error : missing ';' before '{' d:\my files\c program\wow\temp\temp.cpp(33) : error C2562: 'set_alpha' : 'void' function returning a value d:\my files\c program\wow\temp\temp.cpp(21) : see declaration of 'set_alpha' d:\my files\c program\wow\temp\temp.cpp(35) : error C2601: 'print_max' : local function definitions are illegal d:\my files\c program\wow\temp\temp.cpp(46) : fatal error C1004: unexpected end of file found Error executing cl.exe. temp.obj - 5 error(s), 0 warning(s) ###### 引用来自“中山野鬼”的答案 引用来自“NealFeng”的答案 定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了 哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接 int alpha[26]; void init_alpha(void){ int i; for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0; } #define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0) void set_alpha(char a){ _CHK_SET(a ,'A','Z'); _CHK_SET(a,'a','z'); } int max_num(void){ int re = alpha[0]; int i; for (i = 1 ; i< 26 ; i++) { if (alpha[i] > re) re = alpha[i]; } return re; } int print_max(void){ int i; int flag = 0; i = max_num(); if (alpha[i] == 0){ return 0; } printf(....); alpha[i] = 0; return 1; } 余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0. 哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。 简洁、明了 ###### 引用来自“水晶之夜”的答案 引用来自“中山野鬼”的答案 引用来自“NealFeng”的答案 定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了 哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接 int alpha[26]; void init_alpha(void){ int i; for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0; } #define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0) void set_alpha(char a){ _CHK_SET(a ,'A','Z'); _CHK_SET(a,'a','z'); } int max_num(void){ int re = alpha[0]; int i; for (i = 1 ; i< 26 ; i++) { if (alpha[i] > re) re = alpha[i]; } return re; } int print_max(void){ int i; int flag = 0; i = max_num(); if (alpha[i] == 0){ return 0; } printf(....); alpha[i] = 0; return 1; } 余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0. 哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。 我测试了你一下你这个代码,还有5个错误。不太理解。。 --------------------Configuration: temp - Win32 Debug-------------------- Compiling... temp.cpp d:\my files\c program\wow\temp\temp.cpp(25) : error C2062: type 'int' unexpected d:\my files\c program\wow\temp\temp.cpp(26) : error C2143: syntax error : missing ';' before '{' d:\my files\c program\wow\temp\temp.cpp(33) : error C2562: 'set_alpha' : 'void' function returning a value d:\my files\c program\wow\temp\temp.cpp(21) : see declaration of 'set_alpha' d:\my files\c program\wow\temp\temp.cpp(35) : error C2601: 'print_max' : local function definitions are illegal d:\my files\c program\wow\temp\temp.cpp(46) : fatal error C1004: unexpected end of file found Error executing cl.exe. temp.obj - 5 error(s), 0 warning(s) 他这个是 C语言写的,得用 C语言编译器。 把 .cpp 改成 .c 再试试。 还有 27 行 printf 里面加上你要输出的东西。 ###### 引用来自“水晶之夜”的答案 引用来自“中山野鬼”的答案 引用来自“NealFeng”的答案 定义个数组c=int[26][2],c[0][0]='a',c[0][1]=次数,然后排序,然后输出,如果次数为0,则不输出,选个排序算法就行了 哈,你这个貌似多做事情了。题目是针对字母,没针对其他分类方法。那么就可以直接 int alpha[26]; void init_alpha(void){ int i; for (i = 0 ; i < 26 ; i ++ ) alpha[i] = 0; } #define _CHK_SET(a,min,max) do {if((a >= (min))&&(a <= (max))){alpha[a-min] += 1;}while (0) void set_alpha(char a){ _CHK_SET(a ,'A','Z'); _CHK_SET(a,'a','z'); } int max_num(void){ int re = alpha[0]; int i; for (i = 1 ; i< 26 ; i++) { if (alpha[i] > re) re = alpha[i]; } return re; } int print_max(void){ int i; int flag = 0; i = max_num(); if (alpha[i] == 0){ return 0; } printf(....); alpha[i] = 0; return 1; } 余下,就是初始化。然后读一个字符如果不是结束符,就掉用一次set_alpha,全部处理完就不停的调用print_max 直到返回为0. 哈, 原型设计不要考虑优化问题。逻辑清楚是关键。有什么好排序的。你排序的价值在于降低不必要的逻辑处理,但和目标逻辑没有关系。 我测试了你一下你这个代码,还有5个错误。不太理解。。 --------------------Configuration: temp - Win32 Debug-------------------- Compiling... temp.cpp d:\my files\c program\wow\temp\temp.cpp(25) : error C2062: type 'int' unexpected d:\my files\c program\wow\temp\temp.cpp(26) : error C2143: syntax error : missing ';' before '{' d:\my files\c program\wow\temp\temp.cpp(33) : error C2562: 'set_alpha' : 'void' function returning a value d:\my files\c program\wow\temp\temp.cpp(21) : see declaration of 'set_alpha' d:\my files\c program\wow\temp\temp.cpp(35) : error C2601: 'print_max' : local function definitions are illegal d:\my files\c program\wow\temp\temp.cpp(46) : fatal error C1004: unexpected end of file found Error executing cl.exe. temp.obj - 5 error(s), 0 warning(s) 这个也算代码?我的老天啊。。。无非是我想说明逻辑,用了语言来描述。。。。不能这么省事。又不是我的作业。哈。

爱吃鱼的程序员 2020-06-03 17:27:32 0 浏览量 回答数 0

问题

备战大厂每日挑战算法,坚持打卡更有社区定制周边奖品等你赢!

被纵养的懒猫 2020-04-07 11:41:45 5309 浏览量 回答数 5

回答

【丁宁-清华大学-阿里达摩院自然语言技术实习体验】 作者简介:丁宁,清华大学计算机科学与技术系2年级博士生,研究方向为自然语言处理、信息抽取、语言表示学习等,在ACL、EMNLP、AAAI、IJCAI等发表多篇文章,作为研究型实习生在阿里达摩院实习半年+。 实习体会 很幸运能来到阿里巴巴进行实习!组里的氛围特别好,同事和师兄师姐都非常专业、友善、亲切。无论是科研上还是工作生活上的任 何问题,都能得到慷慨的帮助。在这里,我认识了一批学术和生活上的榜样(我的主管每天都吃健康餐,而我牛肉汤泡饼),结交了志同道合的朋友(排队喝牛肉汤回来写论文的日子),见识到了IT同学的认真负责(远程帮我调试打印机,周末修电脑),见过了马云老师,也亲身经历了一次双十一奋战。阿里的科研积淀和文化氛围都让我感到收获颇丰,感谢阿里巴巴提供研究型实习生这一高水平项目,也期待更多的同学可以加入研究型实习生的大家庭。 科研心得& 工作宣传 今年在阿里巴巴所做的跨领域分词工作被ACL 2020高分接收,其中meta review说“well-written, well-motivated with strong results, sure accept”。其实这句话可以很好地总结评判科研论文好坏的标准,实际上或许现阶段的科研也并没有什么秘密,动机明确、方法得当、实验充分,就可以形成一篇不错的科研论文。当然了,如果想做出让领域内眼前一亮的工作,可能就需要一些灵光一闪了。 具体到我们的工作上来,跨领域任务往往面临目标领域精标注数据缺失的问题,具体到分词任务上来说,这种数据缺失往往会导致OOV和词的分布差异问题。本文通过弱监督启发式算法来进行远程标注,并引入对抗学习来进行降噪。本文的实验中以newswire (新闻语料)作为源领域,在5个不同的目标领域数据上都取得了较好的效果。 这个工作或许有助于我们真正的往跨领域的两个通用问题上去设计了相关的解决办法。论文名字:《Coupling Distant Annotation and Adversarial Training for Cross-Domain Chinese Word Segmentation》,具体可以查看达摩院的官方宣传~:ACL 2020有哪些值得关注的论文? - 阿里巴巴达摩院的回答 - 知乎https://www.zhihu.com/question/385259014/answer/1190808208 另外,也宣传一下作为co-author的另一篇ACL 2020论文,是实习生同事周洁(上海交大研究生)的工作,瞄准多层级文本分类任务,设计层级敏感编码器将多层结构作为有向图建模,并且实现了一个串行和并行的版本,论文名字:Hierarchy-Aware Global Model for Hierarchical Text Classification。 还有另一个实习生同事张浩宇(国防科大博士生)在IJCAI 2020的工作,使用noisy learning的方法去进行远程监督entity typing降噪,方法非常优雅,论文名字:Learning with Noise: Improving Distantly-Supervised Fine-grained Entity Typing via Automatic Relabeling。 【杜志浩-哈尔滨工业大学-我在达摩院作实习研究僧的那些事儿】 经韩老师介绍,2019年7月,有幸进入阿里巴巴达摩院成为一名实习研究僧。如今也已半年有余,期间发生的事情仍然历历在目。从初出茅庐的不安,到积极融入的快乐,再到宠辱不惊的泰然,一路走来收获良多! 初出茅庐 其实,刚到达摩院语音算法组时,我的内心充满了不安。这种不安来自于初出茅庐的不自信,不知自己能否胜任这份工作,为公司带来效益。同时,也来自于环境转变的不适应,换了一个全新的环境,对公司内的工作方式、待人接物都不甚了解。 但是,在算法组师兄师姐的帮助下,我的这些不安很快就烟消云散了。为了能够使我尽快熟悉工作内容、了解工作方式,雷鸣师兄坚持每周四晚上为实习生开组会,拉着仕良哥、智颖等很多小伙伴一起讨论算法思路和实验中遇到的问题。我想他们应该都挺忙的吧,但还是牺牲自己休息的时间来参加组会。 刚来的那段时间,除了“雷老师,xxx麻烦审批通过一下”以外,我说的最多的恐怕就是“xx姐/哥,xxx在哪”。由于对很多事情都不了解,比如服务器怎么申请啊,oss怎么弄啊,我总是要麻烦逍北姐、遥仙哥等目之所及的小伙伴。他们一边在忙自己的工作一边还不厌其烦的告诉我,为我提供了莫大的帮助。 积极融入 在算法组这段时间,让我印象最为深刻的一句话就是“我们做事情都很直接,有什么问题,就带着方案提出来”。以前,总是被教育和鼓励发现问题,在阿里,找到问题只是完成了第一步,还需要再提出一个切实可行的解决方案。期间发生的一段小插曲让我现在依然记忆犹新。  为了准备910,语音测试组的小伙伴每天都在紧张的进行测试。其中一项是对语音实时转录及翻译软件的稳定性测试。由于已经进入应用阶段,不能在直接将数据送入到模型中,需要将语音播放出来,再由软件录音进行测试。播放的内容是马老师的演讲,对于坐在旁边的小伙伴来说既是一件好事,也是一件坏事。由于马老师的演讲实在太引人入胜了,每次他们进行测试时,我们都无法专心工作,最终只能……。 咳咳,我心想,这么下去也不是事儿啊,梦想要有,生活也得继续啊,得想想办法解决一下这个问题。我尝试了各种办法,但似乎都无法绕过功放这个问题。最终功夫不负有心人,找到了一款虚拟声卡的软件,能够将一个应用程序的音频输出直接作为另一个应用程序的输入。在熟悉过这个软件的使用方式后,我找到测试组的组长,向他提出了我现在的处境和解决方案。他告诉我,他也知道这样会打扰到周边的人,但是之前也没有太好的办法,感谢我提出的解决方案。 虽然这只是实习期间的一段小插曲,但是我依然印象深刻。通过这件事,我践行了带着方案提问题,这一阿里人所特有的工作方式,让我感觉自己正在逐渐融入到这个集体当中。 宠辱不惊 经过几个月“死去”又“活来”的做实验、写论文,我跟雷鸣师兄合作的语音增强相关工作投稿到了ICASSP 2020。这是语音信号处理领域的顶级会议,在来阿里之前,我也投稿过一次,但不幸被拒。为了准备这篇文章,雷鸣师兄跟我保持着很高互动,了解实验进度,适时的进行指导。此外,还有仕良哥帮助我进行语音畸变的评估。 2020年1月25日这一天,是我国的传统节日,春节,同时也是ICASSP出结果的日子。在得知结果前,我的内心非常忐忑。但当得知接收的喜讯时,我反而没有想象中那么兴奋,没有想象中那么高兴。我的第一反应是看看审稿人的意见,看看我专家们对我文章的看法,还有哪些不足和需要改进的地方。 我想宠辱不惊的心态应该是我在阿里的一个重要收获吧,不以物喜不以己悲。尽力做好自己该做的事儿,结果自然水到渠成。 再说两句 在阿里的这段实习使我受益匪浅。这里有乐于助人、善解人意的师兄师姐,也有认真负责、要求严格的主管Leader;有弹性自由的工作时间,也有肝到深夜的满腔热情;有最新最热的研究成果,也有成熟稳定的应用软件。这里不像实验室的象牙塔,关注技术的同时,也更关注技术如何落地、如何应用到生活中去,最终如何造福亿万用户。 韩鹏-KAUST-青春没有我之阿里巴巴天猫精灵争夺赛被迫写的研究心得 竞选宣言: 在阿里实习摸了几个月的鱼,最开心的就是又吃到了祖国的美食,虽然杭州的食物实在是太清淡了,但总比我在沙特每天吃水煮青菜不放盐要好很多。在阿里的这几个月,让我看淡了很多,发现生命里比较重要的就是长在自己脑袋上的头发,不能太年轻就失去他们。女网红我是感觉自己这辈子没机会了,毕竟流量明星也不是靠推荐算法能捧红的,也就希望能够得到这次500块钱的天猫精灵,请大家pick我。 研究心得: 多抱大腿 为了凑足300字的内心情感白描: 这个世界实在是太无聊了,尤其疫情导致的只能居家办公,我已经憋得快精神失常了,虽然平时也不是那么正常。希望这个世界早日恢复原来的美好,我还打算去越南胡志明市的日式KTV感受一下女仆装呢,希望疫情不会让这些服务业倒闭呢吧。 居然还不够300字,感觉生命浪费在写文字上要比大保健上还是好一些的,希望这些文字能够启发你,虽然我感觉也并没有什么意义,而人活着的意义又是什么呢? 【韩镕罄-南加州大学- 阿里研究型实习生体验】 简介: 经过两年研究时间,找到了学校的教职,也找到了老婆,感谢阿里~ 2018年八月来阿里做研究型实习生,本人在南加州大学商学院读Operations Management 的Ph.D. 块两年时间做了几篇 field experiment paper, 感觉阿里有太多好玩有趣的商业问题可以讨论直接研究。 通过和阿里的合作顺利找到UIUC 伊利诺伊大学香槟分校的常任轨教职。 更神奇的是,在实习期间,随便刷个阿里妹儿的相亲帖, 加个微信 聊一聊 发现和自己一天生日。 就是你了!现在已经结婚快半年! 三十而立,一切静好,感谢阿里! 【马腾-清华大学- 阿里巴巴RI项目心得】 我与阿里之缘 在2019年的夏天,后来成为我主管的文侑来到清华进行交流,当时的我刚刚完成了一个学术项目的研究,正在寻求于之后的研究方向。恰好在交流会上碰见了文侑,经过一番交流之后吗,了解到操作系统团队是阿里 RDMA 技术的先行者和推广者,这正是我计划之后想要研究的方向,于是便一拍即合。由于我之前所研究的领域刚好符合是阿里目前正在做的一些项目,所以文侑提供了一个可以在阿里实习的机会。 在通过了多轮面试之后,我终于成功的入职了操作系统内核组作为学术型实习生。从2018年九月初入职至今,将近两年的时间,我也逐渐地适应了在阿里的生活,松弛有度而又充满欢乐。在这里我也结识了许多要好的朋友,并且,通过公司组织的各种聚会和团建的活动,让我解释了许多有着共同语言爱好的伙伴,大家给与了我这个新人很多的帮助和照顾,使我也渐渐地融入了这个有爱的团队。 在阿里的学术成果 在阿里实习期间,在同事们的帮助下,我顺利地完成了两个与我所在实验室合作的学术项目,并且这两个项目也幸运的产出了两篇高质量的论文,分别发表在了不同领域的高水平会议当中。 其中,第一篇论文发表在第21届Cluster会议,与2019年在美国阿尔伯克基召开。Cluster 是高性能计算方向计算机系统领域的主要会议,这个工作提出并实现了统一高效的 RDMA 消息中间件,解决了 RDMA 在实际生产过程中的一些关键可靠性和可用性问题,例如:极简的接口抽象,必要的上层消息确认机制,中间件辅助流控配合 DCQCN,结合生产系统的诊断机制等等,目前该技术已经被广泛应用在阿里巴巴基础云产品中(包括:数据库,分布式存储等)。另外一个工作则发表在了第25届 ASPLOS会议。ASPLOS 是操作系统,体系结构和编程语言三个方向综合的计算机系统领域顶级会议。这篇论文是和我所在的清华高性能所合作完成的,文章中第一次提出了利用RDMA将数据中心的NVM做disaggregation, 实现了高效的框架,同时证明了这种新架构的可行性。 在阿里的感想 阿里巴巴操作系统团队是一直致力于建立和完善系统领域工业界和学术界的纽带,并且在持续实践工业界和学术界之间的问题分享和工作互动,他们希望通过这些分析和互动能够更好地促进中国在世界计算机系统领域的整体发展和创新。作为操作系统团队中的一员,我深切了解到了先进技术对于企业发展的重要性,在实习的过程中,同我所在的实验室进行合作,我更是深深感受到只有通过学术与工业相辅相成,才能够真正让企业发展先进技术。另外一方面,经过一段时间的实习,我对所在的操作系统团队和阿里技术部门的工作有了更深入的了解,我对自己也有了进一步的规划,计划在毕业之后能够入职阿里,通过我的努力,继续在追逐技术之路上奋斗着。 【亓家鑫-新加坡南洋理工大学- 阿里云实习心得】 非常荣幸我们的研究工作*《Two causal principles for improving visual dialog》*获得了同行的认可,并收录在CVPR 2020会议中。在此要特别感谢我的教授,MReaL实验室成员以及阿里城市大脑实验室师兄师姐一直以来的支持和帮助。比起论文本身的内容,我更希望跟大家分享一年来做研究的心得和感悟,虽然目前我仍然是一个萌新,不过我希望通过萌新的角度能带给大家一些研究上的启发。 开始一个研究之前,选择方向很重要。当然,每一个方向都有自己的优缺点,比如新的方向“容易”发文章,可能将其他领域原有的方法引入加一些调整就可以达到比较高的结果。不过如果没有坚实的创新,在同行评议时,可能会受到质疑。一旦没有通过,再转投时可能发现已经落后于其他人。“老“的方向可能会感觉灌水困难,不过因为我没有真正做过经典的方向,所以不太好发表评论。根据观察,在一堆全面而又坚实的研究中找到创新点,对萌新来说确实困难,不过一旦有所突破,肯定会对这个社区产生广泛的影响。作为一个萌新,可能不会自己选择方向或者领域,所以接受导师或者主管的安排成了唯一的选择,不过要相信自己的导师和主管,因为大家都是在帮助你,而且他们经验丰富。只有当自己走完一套研究的流程,并且真正找到自己感兴趣或者觉得可以有所突破的方向,那可能才是真正属于自己的研究的开始。 当选定了方向,开始做研究的时候,清楚的了解所有有关的方法是非常重要的,因为这样可以防止你的idea被存在的方法“抄袭“。其实对一个比较成熟的研究方向来说,简单思考得到的idea一般都会被提出过。不过研究完所有存在方法后,要跳出这些方法,因为阅读他们的方法可能不是来借鉴,更多的是防止撞车,想要真正有创新,在别人的方法上改动往往是不够的,这就要求我们重新审视这个任务甚至数据集的每一个样本。当然目前即使是学术界toy的数据集也有动辄几十万的数据量,看完是不可能的,不过根据自己的思路统计一些数据特征,有时候对研究会产生很大的帮助。当觉得自己已经掌握了这个数据集或者这个任务的时候,应该是跑一些baseline来练习了。 我作为萌新,没有从零开始写,而是找了一个现成的模型开始修改,这样难度会减少很多,不过毕竟是别人的代码,还是有很多不舒服的地方,所以等自己成熟了的时候,有空的时候,一定要从头写一遍。当然我也不知道什么时候有空。当我开始修改baseline的时候,此次的研究旅行就算是上路了,在接受导师的指引的同时也可以自己不断的尝试自己的想法,因为不知道什么是有用的。我作为萌新刚开始的感受是我觉得可能我想的都有用,那一定要去试一下,所以我也建议大家多试一下,说不定真的有用呢,反正电费不花自己的。当一个东西有用的时候,就可以来思考他为什么有用了,当你想好它为什么有用并且通过了广泛的测试,就到了跟大家分享成果的时候。 当然,一个有用的idea背后可能有无数个没用的idea,至于他们为什么没用,我觉得如果实在是有兴趣,可以研究一下,但是有时候会花大量的时间。举一个实际的例子,我在去年做visual dialog比赛,大概四月份就发现了一个有用的方法,之后也顺利的拿到了第一并且在此基础上进行探究和扩展发表了自己的成果。不过同时,当时有一个效果降低的操作一直困扰着我,直到六个月以后,当然这六个月中还做了其他的事情,我才发现了它真正的原因,并且最终变成了我文章中的一句话。举这个例子的目的是,研究没有效果的idea会对研究有所帮助,不过可能会收益较低。 研究成果的发表是一个很重要的过程,它可以给领域内的同行以启发,甚至可以影响本领域之外的人,所以有时候高度总结自己的思想是一件有用的事情。比如我所做的工作我认为进行高度总结之后可以得到一个启发是:对多模态任务来说不一定所有模态都是平等的,对模型来说所存在模态也不一定是影响结果的全部。除了对自己motivation的总结,应用细节以及结果展示也是非常重要的,因为我是萌新,怎样写出一篇文章的经验肯定是不足的,所以在此不再赘述。在发表完文章之后,“售后服务“也是非常重要的一点,这也是我的教授教我的很重要的理念。因为发表的内容不是刊登出来就结束了,而是你对社区贡献的开始,之后做研究可能会发现更好的实现,或者当时的理论没有讲清楚完善,这些都可以补充到自己的代码中,让大家更好的了解你的思路和工作,或许以后还能收获好评。 此外,实验室的成员就是自己研究道路上的引导者和伙伴,会对自己的研究产生各种各样至关重要的影响,大多时候大家都不会吝惜跟你讨论分享自己的观点,有时还会亲自帮助你解决问题,所以要记得经常参加团建和小集体聚会。不过也不能太依赖别人,每当遇到问题的时候,特别是技术性的问题,还是依靠自己解决的好,毕竟未来总会离开实验室,离开乐于帮助你的人。最后,保护好自己的头发,还是要早睡早起,调不出来的bug熬夜也调不出来,不work的idea可能真的不work,没有人保证炼出来的一定是金子,不要过分影响正常的作息,毕竟这不是百米赛跑,也不能算是马拉松,而是长久的起码好几年以上要坚持的事业。不过我作为萌新才刚刚起步,依然没有体会到最艰难的时刻,不过做好心理准备还是应该的,该来的总是会来的。最后的最后希望这些浅显的经验总结能够给大家带来一点儿帮助,谢谢大家的阅读。 【田冰川-南京大学- 在阿里网络团队实习两年是一种怎样的体验?】 简介: 大家好!我是田冰川,南京大学2016级直博生,导师为田臣老师,研究方向为计算机网络。2018年6月,我以研究型实习生的身份入职阿里巴巴基础设施事业部网络研究团队,实习期间主要从事网络验证相关的研究工作,即通过形式化方法与灰度测试,来降低网络变更中的潜在风险。 2018年既是网络研究团队刚刚组建的一年,也是研究型实习生在阿里刚刚起步的一年。这年春天,经我导师田臣老师介绍,我参加了研究型实习生面试,加入了网络研究团队。 来到团队后,我参加的第一个研究项目是“金睛”,用以保障复杂ACL变更的正确性。ACL即访问控制列表,网络中的ACL决定着流量的连通性。网络架构演化有时会伴随着对ACL的迁移,如何保证迁移前后网络连通性是等价的,是困扰架构与运营部门的一大难题,而金睛项目则是为该问题而生。项目落地以来,金睛系统多次在骨干网ACL迁移中对变更方案进行了验证,并逐渐扩展至对边缘网络的验证。相关论文发表于SIGCOMM 2019主会,我在会场进行了20余分钟的演讲,与我们团队的另一篇文章HPCC共同成为阿里集团在网络领域top1学术会议主会中的首次亮相。 时间总是过的很快。转眼间,我来阿里已经两年了,自金睛之后,又陆续参与了多个研究课题。在阿里的时间越久,就越能切身体会到学术界研究与工业界研究的不同。在阿里实习以来,我接触到的所有研究课题,都不是凭空“想”出来的空中楼阁,更不是靠别人论文“启发”出来的二手课题,而是源自于真实业务的现阶段瓶颈与下一阶段发展趋势——这一点是高校科研很难做到的。 这两年间,我对科研这件事的心态也发生了进一步的变化。2017年,来到阿里之前,我的论文达到了学校博士毕业的最低要求,相当于没有了毕业之忧,对科研的心态从“先拿到博士学位再说”,变成了“想要做出点什么,不想让自己的博士5年就这么水过去”;在来到阿里,接触到工业界的前沿课题之后,我对科研的心态再一次发生了转变,变成“因为认可一件事的价值,所以想要去做好”——这已经成为一种内在的驱动力,让我在认真工作的同时,享受研究带来的乐趣。 如果一切顺利的话,我将于2021年6月博士毕业。能在阿里巴巴度过专属实习生的“三年醇”,想必也是人生中的一大成就了! 【吴秉哲-北京大学- 吴师傅的博士研究课题:大数据时代的数据隐私研究方向初探】 加上本科的时间,不知不觉已经在燕园里面呆了八年了,明年不出意外应该就会离开学校去业界工作。准备最近以文章的形式梳理一下博士几年的研究以及生活的心路历程。由于内容比较分散,所以决定分为几个不同的部分。这次推送封面图片是16年骑行到加乌拉山口遥看喜马拉雅山脉的图片,而我在阿里的花名是风远,意为远处的风。希望多年之后,还有一颗少年的心,投入每天永不变。这次借着阿里内部一个活动的机会,写了今天的这篇稿子,为大家介绍一下我的thesis topic。 已经在蚂蚁实习了一年了,一年时光匆匆而过,而在蚂蚁金服度过的这段时光带给了我很多研究以及生活中的体验,这一年里学到的经验也将伴随着我之后的研究之路。 我本科四年是在数院度过,在研究生阶段决定转换方向到计算机系。博士的前两年一直在跌跌撞撞地寻找自己的研究方向,尝试过很多方向均以失败告终。终于在第三年的时候,误打误撞开始研究起机器学习的隐私保护问题并找到了很多灵感,开始沉淀了一些基本的研究工作。有一天我从一个朋友那里听到了她关于金服这边隐私保护机器学习的团队介绍,当时我就决定要到业界的前沿去看一看隐私保护的真实业界需求。在此之前,我已经在谷歌,IBM等公司有过多段实习的经历,但是在蚂蚁这一次实习经历,是与我自己研究方向最接近,也是时间最长的一次。借着这次约稿的机会,以此文简单总结一下自己过去两年在这一方向的研究。 隐私保护与共享学习 目前随着各种机器学习算法在集团的业务落地,许多隐私泄露与数据滥用的风险相继而来。 尤其是在蚂蚁金服这样一个拥有很多支付数据的企业,数据安全以及隐私保护的重要性更是不言而喻。站在商业合作的角度,如何实现不同公司或者部门之间的数据共享学习也是我所在的团队现在攻坚的一个问题。在这样一个研究背景下,我来到了蚂蚁金服的共享智能团队,开始和师兄师姐们从不同的维度对上述问题展开了深入的研究。 共享学习这样一个概念听起来很美好,但是实际落地起来却困难重重,需要考虑到上层软件算法的设计以及底层系统和硬件的优化,才有可能真正在实际的业务中兼顾效率和隐私保护强度。共享智能团队在这一方向上有着得天独厚的优势。一是领先的业务场景,在国际同行好多还停留在学术研究阶段时,我们团队已经和国内多家银行有了合作。另一个则是技术沉淀的领先。因为金服自身业务的特殊性,我们团队很早就开始了隐私保护机器学习和共享学习的布局,包括很多原始的技术沉淀,强大的工程团队以及学术预研团队。这些积累也使得我们能够很快地摸清最新的一些研究成果并能将其吸入到我们自己的系统当中。 我自己关于隐私保护机器学习的研究主要是围绕着三个层面展开,分别是理论,算法设计,以及系统和硬件优化。在理论层面,我主要针对现有的各种机器学习算法,建立相应的隐私泄露分析框架,比如我们在之前的工作中,针对一种常用的贝叶斯学习的算法根据雷尼差分隐私建立了隐私泄露的定量分析框架,我们进一步使用我们的框架和已有的一些泛化误差上界做了联系,从而能从多个角度去解释该算法的隐私泄露原因。在算法设计层面,我们针对各种已有的新兴算法以及场景,比如图神经网络,推荐系统建立了相应的共享学习算法,并利用我们的理论框架,对这些算法的隐私保护强度做了定量的评估。除开上层的理论和算法设计,底层的系统和硬件的优化同样是非常重要的一环。 在我们团队,我们主打基于硬件可信执行环境 (TEE)的机器学习serving系统,我针对我们当前这套服务系统,结合神经网络计算的一些特点,定制了该系统的一系列优化措施大大提升了整个系统的吞吐量。我也将其中一些措施注册了专利,并在前几天得到了内部的专利授权。除开上述介绍的学术研究方面的成果,我也参与了IEEE共享学习标准的制定会议,这也使得我从标准制定者的角度去更深地思考如何使用技术在未来社会中实现隐私与效率的兼顾。 总之,我自己很感谢能成为共享智能团队的一员,我在这里学到的最宝贵的经验就是详细地从上到下了解了这样一个大团队的合作与分工,学习他们是如何一步步从最初的需求分析,算法设计,到最后真正的业务落地。也很高兴和各位共享智能的同事度过自己博士生涯中很重要的一年。也非常感谢我的博士导师对我研究的无条件支持。回看博士这一路的艰辛,也是感慨万千。有点像自己之前高原骑行的经历,经历了爬到坡顶的缺氧与无力,终在转角处遇见了骑行途中最美的雪山风光。

游客bnlxddh3fwntw 2020-05-19 16:05:51 0 浏览量 回答数 0

问题

十大经典排序算法最强总结(内含代码实现)

游客pklijor6gytpx 2020-01-09 14:44:55 1240 浏览量 回答数 2

问题

Nginx性能为什么如此吊

小柒2012 2019-12-01 21:20:47 15038 浏览量 回答数 3

问题

Web测试方法

技术小菜鸟 2019-12-01 21:41:32 7022 浏览量 回答数 1

回答

92题 一般来说,建立INDEX有以下益处:提高查询效率;建立唯一索引以保证数据的唯一性;设计INDEX避免排序。 缺点,INDEX的维护有以下开销:叶节点的‘分裂’消耗;INSERT、DELETE和UPDATE操作在INDEX上的维护开销;有存储要求;其他日常维护的消耗:对恢复的影响,重组的影响。 需要建立索引的情况:为了建立分区数据库的PATITION INDEX必须建立; 为了保证数据约束性需要而建立的INDEX必须建立; 为了提高查询效率,则考虑建立(是否建立要考虑相关性能及维护开销); 考虑在使用UNION,DISTINCT,GROUP BY,ORDER BY等字句的列上加索引。 91题 作用:加快查询速度。原则:(1) 如果某属性或属性组经常出现在查询条件中,考虑为该属性或属性组建立索引;(2) 如果某个属性常作为最大值和最小值等聚集函数的参数,考虑为该属性建立索引;(3) 如果某属性经常出现在连接操作的连接条件中,考虑为该属性或属性组建立索引。 90题 快照Snapshot是一个文件系统在特定时间里的镜像,对于在线实时数据备份非常有用。快照对于拥有不能停止的应用或具有常打开文件的文件系统的备份非常重要。对于只能提供一个非常短的备份时间而言,快照能保证系统的完整性。 89题 游标用于定位结果集的行,通过判断全局变量@@FETCH_STATUS可以判断是否到了最后,通常此变量不等于0表示出错或到了最后。 88题 事前触发器运行于触发事件发生之前,而事后触发器运行于触发事件发生之后。通常事前触发器可以获取事件之前和新的字段值。语句级触发器可以在语句执行前或后执行,而行级触发在触发器所影响的每一行触发一次。 87题 MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。具体原因为:MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。 86题 建立索引的时候一般要考虑到字段的使用频率,经常作为条件进行查询的字段比较适合。如果需要建立联合索引的话,还需要考虑联合索引中的顺序。此外也要考虑其他方面,比如防止过多的所有对表造成太大的压力。这些都和实际的表结构以及查询方式有关。 85题 存储过程是一组Transact-SQL语句,在一次编译后可以执行多次。因为不必重新编译Transact-SQL语句,所以执行存储过程可以提高性能。触发器是一种特殊类型的存储过程,不由用户直接调用。创建触发器时会对其进行定义,以便在对特定表或列作特定类型的数据修改时执行。 84题 存储过程是用户定义的一系列SQL语句的集合,涉及特定表或其它对象的任务,用户可以调用存储过程,而函数通常是数据库已定义的方法,它接收参数并返回某种类型的值并且不涉及特定用户表。 83题 减少表连接,减少复杂 SQL,拆分成简单SQL。减少排序:非必要不排序,利用索引排序,减少参与排序的记录数。尽量避免 select *。尽量用 join 代替子查询。尽量少使用 or,使用 in 或者 union(union all) 代替。尽量用 union all 代替 union。尽量早的将无用数据过滤:选择更优的索引,先分页再Join…。避免类型转换:索引失效。优先优化高并发的 SQL,而不是执行频率低某些“大”SQL。从全局出发优化,而不是片面调整。尽可能对每一条SQL进行 explain。 82题 如果条件中有or,即使其中有条件带索引也不会使用(要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引)。对于多列索引,不是使用的第一部分,则不会使用索引。like查询是以%开头。如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。如果mysql估计使用全表扫描要比使用索引快,则不使用索引。例如,使用<>、not in 、not exist,对于这三种情况大多数情况下认为结果集很大,MySQL就有可能不使用索引。 81题 主键不能重复,不能为空,唯一键不能重复,可以为空。建立主键的目的是让外键来引用。一个表最多只有一个主键,但可以有很多唯一键。 80题 空值('')是不占用空间的,判断空字符用=''或者<>''来进行处理。NULL值是未知的,且占用空间,不走索引;判断 NULL 用 IS NULL 或者 is not null ,SQL 语句函数中可以使用 ifnull ()函数来进行处理。无法比较 NULL 和 0;它们是不等价的。无法使用比较运算符来测试 NULL 值,比如 =, <, 或者 <>。NULL 值可以使用 <=> 符号进行比较,该符号与等号作用相似,但对NULL有意义。进行 count ()统计某列的记录数的时候,如果采用的 NULL 值,会被系统自动忽略掉,但是空值是统计到其中。 79题 HEAP表是访问数据速度最快的MySQL表,他使用保存在内存中的散列索引。一旦服务器重启,所有heap表数据丢失。BLOB或TEXT字段是不允许的。只能使用比较运算符=,<,>,=>,= <。HEAP表不支持AUTO_INCREMENT。索引不可为NULL。 78题 如果想输入字符为十六进制数字,可以输入带有单引号的十六进制数字和前缀(X),或者只用(Ox)前缀输入十六进制数字。如果表达式上下文是字符串,则十六进制数字串将自动转换为字符串。 77题 Mysql服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。 76题 在缺省模式下,MYSQL是autocommit模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,mysql是不支持事务的。但是如果你的MYSQL表类型是使用InnoDB Tables 或 BDB tables的话,你的MYSQL就可以使用事务处理,使用SET AUTOCOMMIT=0就可以使MYSQL允许在非autocommit模式,在非autocommit模式下,你必须使用COMMIT来提交你的更改,或者用ROLLBACK来回滚你的更改。 75题 它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。 74题 创建索引的时候尽量使用唯一性大的列来创建索引,由于使用b+tree做为索引,以innodb为例,一个树节点的大小由“innodb_page_size”,为了减少树的高度,同时让一个节点能存放更多的值,索引列尽量在整数类型上创建,如果必须使用字符类型,也应该使用长度较少的字符类型。 73题 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下: 限定数据的范围: 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内。读/写分离: 经典的数据库拆分方案,主库负责写,从库负责读。垂直分区: 根据数据库里面数据表的相关性进行拆分。简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。水平分区: 保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。水平拆分可以支撑非常大的数据量。 72题 乐观锁失败后会抛出ObjectOptimisticLockingFailureException,那么我们就针对这块考虑一下重试,自定义一个注解,用于做切面。针对注解进行切面,设置最大重试次数n,然后超过n次后就不再重试。 71题 一致性非锁定读讲的是一条记录被加了X锁其他事务仍然可以读而不被阻塞,是通过innodb的行多版本实现的,行多版本并不是实际存储多个版本记录而是通过undo实现(undo日志用来记录数据修改前的版本,回滚时会用到,用来保证事务的原子性)。一致性锁定读讲的是我可以通过SELECT语句显式地给一条记录加X锁从而保证特定应用场景下的数据一致性。 70题 数据库引擎:尤其是mysql数据库只有是InnoDB引擎的时候事物才能生效。 show engines 查看数据库默认引擎;SHOW TABLE STATUS from 数据库名字 where Name='表名' 如下;SHOW TABLE STATUS from rrz where Name='rrz_cust';修改表的引擎alter table table_name engine=innodb。 69题 如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);哈希索引也不支持多列联合索引的最左匹配规则;B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。 68题 decimal精度比float高,数据处理比float简单,一般优先考虑,但float存储的数据范围大,所以范围大的数据就只能用它了,但要注意一些处理细节,因为不精确可能会与自己想的不一致,也常有关于float 出错的问题。 67题 datetime、timestamp精确度都是秒,datetime与时区无关,存储的范围广(1001-9999),timestamp与时区有关,存储的范围小(1970-2038)。 66题 Char使用固定长度的空间进行存储,char(4)存储4个字符,根据编码方式的不同占用不同的字节,gbk编码方式,不论是中文还是英文,每个字符占用2个字节的空间,utf8编码方式,每个字符占用3个字节的空间。Varchar保存可变长度的字符串,使用额外的一个或两个字节存储字符串长度,varchar(10),除了需要存储10个字符,还需要1个字节存储长度信息(10),超过255的长度需要2个字节来存储。char和varchar后面如果有空格,char会自动去掉空格后存储,varchar虽然不会去掉空格,但在进行字符串比较时,会去掉空格进行比较。Varbinary保存变长的字符串,后面不会补\0。 65题 首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。 64题 建立索引的时候一般要考虑到字段的使用频率,经常作为条件进行查询的字段比较适合。如果需要建立联合索引的话,还需要考虑联合索引中的顺序。此外也要考虑其他方面,比如防止过多的所有对表造成太大的压力。这些都和实际的表结构以及查询方式有关。 63题 存储过程是一些预编译的SQL语句。1、更加直白的理解:存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。2、存储过程是一个预编译的代码块,执行效率比较高,一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率,可以一定程度上确保数据安全。 62题 密码散列、盐、用户身份证号等固定长度的字符串应该使用char而不是varchar来存储,这样可以节省空间且提高检索效率。 61题 推荐使用自增ID,不要使用UUID。因为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降。总之,在数据量大一些的情况下,用自增主键性能会好一些。 60题 char是一个定长字段,假如申请了char(10)的空间,那么无论实际存储多少内容。该字段都占用10个字符,而varchar是变长的,也就是说申请的只是最大长度,占用的空间为实际字符长度+1,最后一个字符存储使用了多长的空间。在检索效率上来讲,char > varchar,因此在使用中,如果确定某个字段的值的长度,可以使用char,否则应该尽量使用varchar。例如存储用户MD5加密后的密码,则应该使用char。 59题 一. read uncommitted(读取未提交数据) 即便是事务没有commit,但是我们仍然能读到未提交的数据,这是所有隔离级别中最低的一种。 二. read committed(可以读取其他事务提交的数据)---大多数数据库默认的隔离级别 当前会话只能读取到其他事务提交的数据,未提交的数据读不到。 三. repeatable read(可重读)---MySQL默认的隔离级别 当前会话可以重复读,就是每次读取的结果集都相同,而不管其他事务有没有提交。 四. serializable(串行化) 其他会话对该表的写操作将被挂起。可以看到,这是隔离级别中最严格的,但是这样做势必对性能造成影响。所以在实际的选用上,我们要根据当前具体的情况选用合适的。 58题 B+树的高度一般为2-4层,所以查找记录时最多只需要2-4次IO,相对二叉平衡树已经大大降低了。范围查找时,能通过叶子节点的指针获取数据。例如查找大于等于3的数据,当在叶子节点中查到3时,通过3的尾指针便能获取所有数据,而不需要再像二叉树一样再获取到3的父节点。 57题 因为事务在修改页时,要先记 undo,在记 undo 之前要记 undo 的 redo, 然后修改数据页,再记数据页修改的 redo。 Redo(里面包括 undo 的修改) 一定要比数据页先持久化到磁盘。 当事务需要回滚时,因为有 undo,可以把数据页回滚到前镜像的状态,崩溃恢复时,如果 redo log 中事务没有对应的 commit 记录,那么需要用 undo把该事务的修改回滚到事务开始之前。 如果有 commit 记录,就用 redo 前滚到该事务完成时并提交掉。 56题 redo log是物理日志,记录的是"在某个数据页上做了什么修改"。 binlog是逻辑日志,记录的是这个语句的原始逻辑,比如"给ID=2这一行的c字段加1"。 redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。 redo log是循环写的,空间固定会用完:binlog 是可以追加写入的。"追加写"是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。 最开始 MySQL 里并没有 InnoDB 引擎,MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog日志只能用于归档。而InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统,也就是 redo log 来实现 crash-safe 能力。 55题 重做日志(redo log)      作用:确保事务的持久性,防止在发生故障,脏页未写入磁盘。重启数据库会进行redo log执行重做,达到事务一致性。 回滚日志(undo log)  作用:保证数据的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。 二进 制日志(binlog)    作用:用于主从复制,实现主从同步;用于数据库的基于时间点的还原。 错误日志(errorlog) 作用:Mysql本身启动,停止,运行期间发生的错误信息。 慢查询日志(slow query log)  作用:记录执行时间过长的sql,时间阈值可以配置,只记录执行成功。 一般查询日志(general log)    作用:记录数据库的操作明细,默认关闭,开启后会降低数据库性能 。 中继日志(relay log) 作用:用于数据库主从同步,将主库发来的bin log保存在本地,然后从库进行回放。 54题 MySQL有三种锁的级别:页级、表级、行级。 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。 死锁: 是指两个或两个以上的进程在执行过程中。因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。 死锁的关键在于:两个(或以上)的Session加锁的顺序不一致。 那么对应的解决死锁问题的关键就是:让不同的session加锁有次序。死锁的解决办法:1.查出的线程杀死。2.设置锁的超时时间。3.指定获取锁的顺序。 53题 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性(脏读,不可重复读,幻读等),可能产生死锁。 乐观锁:乐观锁不是数据库自带的,需要我们自己去实现。 悲观锁:在进行每次操作时都要通过获取锁才能进行对相同数据的操作。 共享锁:加了共享锁的数据对象可以被其他事务读取,但不能修改。 排他锁:当数据对象被加上排它锁时,一个事务必须得到锁才能对该数据对象进行访问,一直到事务结束锁才被释放。 行锁:就是给某一条记录加上锁。 52题 Mysql是关系型数据库,MongoDB是非关系型数据库,数据存储结构的不同。 51题 关系型数据库优点:1.保持数据的一致性(事务处理)。 2.由于以标准化为前提,数据更新的开销很小。 3. 可以进行Join等复杂查询。 缺点:1、为了维护一致性所付出的巨大代价就是其读写性能比较差。 2、固定的表结构。 3、高并发读写需求。 4、海量数据的高效率读写。 非关系型数据库优点:1、无需经过sql层的解析,读写性能很高。 2、基于键值对,数据没有耦合性,容易扩展。 3、存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,而关系型数据库则只支持基础类型。 缺点:1、不提供sql支持,学习和使用成本较高。 2、无事务处理,附加功能bi和报表等支持也不好。 redis与mongoDB的区别: 性能:TPS方面redis要大于mongodb。 可操作性:mongodb支持丰富的数据表达,索引,redis较少的网络IO次数。 可用性:MongoDB优于Redis。 一致性:redis事务支持比较弱,mongoDB不支持事务。 数据分析:mongoDB内置了数据分析的功能(mapreduce)。 应用场景:redis数据量较小的更性能操作和运算上,MongoDB主要解决海量数据的访问效率问题。 50题 如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。 49题 分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。 48题 除了缓存服务器自带的缓存失效策略之外(Redis默认的有6种策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种: 1.定时去清理过期的缓存; 2.当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。 两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,可以根据应用场景来权衡。 47题 Redis提供了两种方式来作消息队列: 一个是使用生产者消费模式模式:会让一个或者多个客户端监听消息队列,一旦消息到达,消费者马上消费,谁先抢到算谁的,如果队列里没有消息,则消费者继续监听 。另一个就是发布订阅者模式:也是一个或多个客户端订阅消息频道,只要发布者发布消息,所有订阅者都能收到消息,订阅者都是平等的。 46题 Redis的数据结构列表(list)可以实现延时队列,可以通过队列和栈来实现。blpop/brpop来替换lpop/rpop,blpop/brpop阻塞读在队列没有数据的时候,会立即进入休眠状态,一旦数据到来,则立刻醒过来。Redis的有序集合(zset)可以用于实现延时队列,消息作为value,时间作为score。Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。当 key 存在但不是有序集类型时,返回一个错误。 45题 1.热点数据缓存:因为Redis 访问速度块、支持的数据类型比较丰富。 2.限时业务:expire 命令设置 key 的生存时间,到时间后自动删除 key。 3.计数器:incrby 命令可以实现原子性的递增。 4.排行榜:借助 SortedSet 进行热点数据的排序。 5.分布式锁:利用 Redis 的 setnx 命令进行。 6.队列机制:有 list push 和 list pop 这样的命令。 44题 一致哈希 是一种特殊的哈希算法。在使用一致哈希算法后,哈希表槽位数(大小)的改变平均只需要对 K/n 个关键字重新映射,其中K是关键字的数量, n是槽位数量。然而在传统的哈希表中,添加或删除一个槽位的几乎需要对所有关键字进行重新映射。 43题 RDB的优点:适合做冷备份;读写服务影响小,reids可以保持高性能;重启和恢复redis进程,更加快速。RDB的缺点:宕机会丢失最近5分钟的数据;文件特别大时可能会暂停数毫秒,或者甚至数秒。 AOF的优点:每个一秒执行fsync操作,最多丢失1秒钟的数据;以append-only模式写入,没有任何磁盘寻址的开销;文件过大时,不会影响客户端读写;适合做灾难性的误删除的紧急恢复。AOF的缺点:AOF日志文件比RDB数据快照文件更大,支持写QPS比RDB支持的写QPS低;比RDB脆弱,容易有bug。 42题 对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。Redis的操作之所以是原子性的,是因为Redis是单线程的。而在程序中执行多个Redis命令并非是原子性的,这也和普通数据库的表现是一样的,可以用incr或者使用Redis的事务,或者使用Redis+Lua的方式实现。对Redis来说,执行get、set以及eval等API,都是一个一个的任务,这些任务都会由Redis的线程去负责执行,任务要么执行成功,要么执行失败,这就是Redis的命令是原子性的原因。 41题 (1)twemproxy,使用方式简单(相对redis只需修改连接端口),对旧项目扩展的首选。(2)codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数改变情况下,旧节点数据可恢复到新hash节点。(3)redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。(4)在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key进行hash计算,然后去对应的redis实例操作数据。这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的代替算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。 40题 (1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 (2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 (3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 (4) 尽量避免在压力很大的主库上增加从库 (5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。 39题 比如订单管理,热数据:3个月内的订单数据,查询实时性较高;温数据:3个月 ~ 12个月前的订单数据,查询频率不高;冷数据:1年前的订单数据,几乎不会查询,只有偶尔的查询需求。热数据使用mysql进行存储,需要分库分表;温数据可以存储在ES中,利用搜索引擎的特性基本上也可以做到比较快的查询;冷数据可以存放到Hive中。从存储形式来说,一般情况冷数据存储在磁带、光盘,热数据一般存放在SSD中,存取速度快,而温数据可以存放在7200转的硬盘。 38题 当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。 37题 分层架构设计,有一条准则:站点层、服务层要做到无数据无状态,这样才能任意的加节点水平扩展,数据和状态尽量存储到后端的数据存储服务,例如数据库服务或者缓存服务。显然进程内缓存违背了这一原则。 36题 更新数据的时候,根据数据的唯一标识,将操作路由之后,发送到一个 jvm 内部队列中。读取数据的时候,如果发现数据不在缓存中,那么将重新读取数据+更新缓存的操作,根据唯一标识路由之后,也发送同一个 jvm 内部队列中。一个队列对应一个工作线程,每个工作线程串行拿到对应的操作,然后一条一条的执行。 35题 redis分布式锁加锁过程:通过setnx向特定的key写入一个随机值,并同时设置失效时间,写值成功既加锁成功;redis分布式锁解锁过程:匹配随机值,删除redis上的特点key数据,要保证获取数据、判断一致以及删除数据三个操作是原子的,为保证原子性一般使用lua脚本实现;在此基础上进一步优化的话,考虑使用心跳检测对锁的有效期进行续期,同时基于redis的发布订阅优雅的实现阻塞式加锁。 34题 volatile-lru:当内存不足以容纳写入数据时,从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。 volatile-ttl:当内存不足以容纳写入数据时,从已设置过期时间的数据集中挑选将要过期的数据淘汰。 volatile-random:当内存不足以容纳写入数据时,从已设置过期时间的数据集中任意选择数据淘汰。 allkeys-lru:当内存不足以容纳写入数据时,从数据集中挑选最近最少使用的数据淘汰。 allkeys-random:当内存不足以容纳写入数据时,从数据集中任意选择数据淘汰。 noeviction:禁止驱逐数据,当内存使用达到阈值的时候,所有引起申请内存的命令会报错。 33题 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。 定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。 32题 缓存击穿,一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。如何避免:在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。 31题 缓存雪崩,是指在某一个时间段,缓存集中过期失效。大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。而缓存服务器某个节点宕机或断网,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。如何避免:1.redis高可用,搭建redis集群。2.限流降级,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。3.数据预热,在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间。 30题 缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。一些恶意的请求会故意查询不存在的 key,请求量很大,对数据库造成压力,甚至压垮数据库。 如何避免:1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。2:对一定不存在的 key 进行过滤。可以把所有的可能存在的 key 放到一个大的 Bitmap 中,查询时通过该 bitmap 过滤。 29题 1.memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型。 2.redis 的速度比 memcached 快很多。 3.redis 可以持久化其数据。 4.Redis支持数据的备份,即master-slave模式的数据备份。 5.Redis采用VM机制。 6.value大小:redis最大可以达到1GB,而memcache只有1MB。 28题 Spring Boot 推荐使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通过spring提供的@ImportResource来加载xml配置。例如:@ImportResource({"classpath:some-context.xml","classpath:another-context.xml"}) 27题 Spring像一个大家族,有众多衍生产品例如Spring Boot,Spring Security等等,但他们的基础都是Spring的IOC和AOP,IOC提供了依赖注入的容器,而AOP解决了面向切面的编程,然后在此两者的基础上实现了其他衍生产品的高级功能。Spring MVC是基于Servlet的一个MVC框架,主要解决WEB开发的问题,因为 Spring的配置非常复杂,各种xml,properties处理起来比较繁琐。Spring Boot遵循约定优于配置,极大降低了Spring使用门槛,又有着Spring原本灵活强大的功能。总结:Spring MVC和Spring Boot都属于Spring,Spring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包。 26题 YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。YAML 的配置文件后缀为 .yml,是一种人类可读的数据序列化语言,可以简单表达清单、散列表,标量等数据形态。它通常用于配置文件,与属性文件相比,YAML文件就更加结构化,而且更少混淆。可以看出YAML具有分层配置数据。 25题 Spring Boot有3种热部署方式: 1.使用springloaded配置pom.xml文件,使用mvn spring-boot:run启动。 2.使用springloaded本地加载启动,配置jvm参数-javaagent:<jar包地址> -noverify。 3.使用devtools工具包,操作简单,但是每次需要重新部署。 用

游客ih62co2qqq5ww 2020-03-27 23:56:48 0 浏览量 回答数 0

回答

虽然跨平台的移动APP开发有利有弊。但从业务初创的角度来看,优点应该是大于缺点的。而且,随着对跨平台移动应用需求的不断增长,现在可用的工具和框架数量也已经很可观了。 但选择过多会令人头疼,这就是为什么我们只关注最突出的跨平台移动开发框架的原因:React Native, Flutter, NativeScript, 和Xamarin。 为了让你更深入地了解是什么使这些工具成为2020年软件开发的可选选项,我们将根据以下标准对它们进行打分:社区支持、基于的编程语言、代码可重用性、性能、界面以及使用它们构建的重要应用程序。 React Native Reaction Native是Facebook于2015年发布的开源、跨平台的应用开发框架。作为2013年举办的一场内部黑客马拉松的产物,它已经成为最受欢迎的原生App开发替代方案之一,拥有2043名GitHub贡献者,获得了超过82900 GitHub标星。不断增长的社区认知度使得找到一支可靠且经验丰富的开发团队来承接你的项目变得相对容易。 Learn Once and Write Anywhere 基于React.JS,React Native利用JavaScript(根据2019年Stack Overflow的调查,JavaScript成为了最受欢迎的编程语言),为Android和iOS用户提供真正原生的应用外观和体验。另外,使该框架脱颖而出的是,如果你需要,React Native允许你使用Java、Objective-C或SWIFT编写部分原生模块来顺利处理复杂的操作,如视频播放或图像编辑。 虽然这些组件不能在不同的平台之间共享,并且需要开发人员做更多的工作,但多达90%的React Native代码是可以重用的。很好地表明该框架的座右铭不是“Write Once, Use Anywhere”,而是“learn once, write anywhere”。 就GUI而言,React Native可以提供接近原生的用户体验,这要归功于它使用了Android和iOS的本地控制器。它还使用带有UI元素的ReactJS库,这有助于加快UI设计过程。在开发移动应用程序时,使此框架值得考虑的另一个原因是,它可用在不丢失应用程序状态的情况下对UI进行更改。 另一个使React Native成为2020年跨平台移动开发框架的首选之一,是因为持续的更新,例如近期的版本 0.60 和 0.61 : 多项辅助功能改进。 更清晰、更人性化的开始屏幕。 快速刷新,融合了实时和热重新加载,从而显著加快了开发进程。 如上的Release Note只是React Native适应不断变化的需求其中一个很小的样本。 2020年值得考虑的第二个框架是Flutter。它在Google I/O 2017上宣布,并于2018年发布,对于跨平台的世界来说,它现在仍然是一个“新人”。但尽管如此,它已经获得了超过80500 GitHub星标和绝大多数工程师将其称为2019年Stack Overflow调查中最受欢迎的三个框架之一,Flutter无疑是一股不可忽视的力量。 Dart是如何使Flutter变得独一无二的 Flutter 背后的编程语言是 Dart,谷歌称之为"客户端优化",适合在任何平台上"快速构建应用程序"。它于 2011 年推出,是一种响应式面向对象的语言,被开发者认为相对容易学习,其中原因有二:第一,语法上它借鉴了C/C++ 和 Java; 第二,在官方网站上,您可以找到内容广泛且相当简单的文档。值得一提的是,Dart 附带了大量Flutter 兼容软件包的软件包,允许您使应用程序更加复杂。 lutter的一个主要优势是,它的性能比本文提到的任何其他跨平台移动开发框架都要好。这归功于Dart的编译器和Flutter拥有自己的一套小部件。结果是它能更快、更直接地与平台直接通信,而不需要JavaScript桥(例如,Reaction Native就是这种情况)。说到小部件:通过Flutter的“UI-as-a-code”方法,它们只用DART编写,这就提高了代码的可重用性。 效率与用户体验和界面密不可分。如前所述,Flutter不依赖于一组原生组件,而是利用可视化、结构化、平台性和交互式小部件进行UI的设计,所有这些都由框架的图形引擎呈现。更重要的是,Flutter留下了很大的定制空间,如果你想要设计一个很完美的UI,它是个很好的选择。 说到Flutter的更新,最新的稳定版本是在12月12日发布的,根据官方发布说明,它合并了来自188个贡献者的近2000个pull。例如,版本1.12.13中包括的改进: 重大的API变动。 新功能,例如SliverOpacity小部件和SliverAnimatedList。 修复了崩溃和性能问题。 Beta版中的Web支持。 这不是一个完整的清单,因为Flutter的目标是让每年发布的四个版本中的每一个版本都能为框架的可用性提升一个台阶。 Flutter是一个年轻的跨平台移动应用程序开发框架,所以它没有像React Native受到众多的大公司青睐也是不足为奇的。然而,这并不意味着它不好,截至2019年12月,它也为阿里巴巴、谷歌广告、Groupon等众多公司和业务所采用。 NativeScript 如果你要开始开发你的产品,“React Native”和“Flutter”绝不是唯一的解决方案。在 2020 年初,适合您的企业的替代框架也可能是 NativeScript。 这个开源框架于2015年3月公开发布,并迅速成为广受欢迎的解决方案。例如,在发布后的短短两个月内,它就获得了3000颗GitHub星标,并在Twitter上吸引了1500多名粉丝的关注。到今天为止,市场上已有超过700个插件可供选择。 在使用NativeScript构建跨平台应用程序时,开发人员首先用JavaScript及其超集TypeScript编写代码。然后,将代码库编译成各自平台原生的编程语言。 另外值得一提的是,使用 NativeScript 的开发人员也可以使用第三方库(CocoaPods 和 Android SDK),而无需包装。 与React Native类似,NativeScript允许访问Android和iOS原生API,这对跨平台应用程序有明显的积极影响。然而,不同之处在于,前者需要构建桥接API,而后者(用Progress首席开发者倡导者TJ VanToll的话说是“将所有iOS和Android API注入JavaScript虚拟机”)。与Facebook框架的另一个相似之处在于代码重用,在这两种情况下都可以达到90%。 Xamarin Xamarin开源框架创建于2011年,这使它成为了这个列表中最“古老“的框架,但直到五年前它被微软收购时,它才获得了发展势头。截至今天,它号称拥有超过6万名贡献者的社区。 从技术上讲,要用Xamarin构建跨平台的移动应用,需要很好地掌握.NET和C#两种技术,前者是使用多种语言(包括C#编程语言)、编辑器和库的开发平台。Xamarin用一组工具补充了上述平台,这些工具有助于构建跨平台应用程序,例如库、编辑器扩展和XAML。第二种技术是C#,这是一种面向对象的编程语言,它被认为比JavaScript学习起来稍难。Xamarin利用这种编程语言编写整个应用程序,从后端到原生API,再到业务逻辑。 Xamarin.Native和Xamarin.Forms Xamarin与其他框架的不同之处在于,它提供了两种编译跨平台移动应用的方式:Xamarin Native(也称为Xamarin.Android/iOS)和Xamarin.Forms。前一种方法优先考虑共享业务逻辑,并通过使用本机接口控件实现近乎本机的性能。 后者侧重于共享代码,而不是业务原理,这一方面会导致代码重用比例增加(使用Xamarin,开发人员可以重用高达96%的C#代码),但另一方面这样会降低代码性能。 您可能已经注意到,跨平台移动应用程序的性能和GUI密切相关,所以如果我说Xamarin构建应用程序的两种方法对界面的最终外观有很大影响,我可能不会感到惊讶。 Xamarin.Android/iOS允许开发人员使用原生控件和布局,而Xamarin.Forms基于标准UI元素,允许从单个API设计应用程序,但如果你需要更完美的原生UI,则可能还不够。 2020年跨平台应用程序开发还值得考虑吗? 不论如何,跨平台确实是一个值得考虑和极具前景的方向,特别是我们上面提到的 “React Native”和“Flutter”。 前者是一个成熟而稳定的框架,利用了最流行的编程语言之一,并拥有成熟的大型开发人员社区。后者是一个快速发展的技术,尽管它比React Native年轻的多,它也已经赢得了世界各地许多开发人员的青睐。 但无论您选择的是“React Native”、“Flutter”还是任何其他框架,跨平台方法都一定会为您节省时间和金钱,同时能为你最大限度地扩大市场覆盖范围。 最后,值不值得考虑,最终还是取决于你的业务目标、预算和时限。 来源;:葡萄城官网

问问小秘 2020-04-15 13:30:17 0 浏览量 回答数 0

回答

Python 简史 开发 Python 3 的想法是实现一些重大的改变,如摆脱了 Python 的遗留问题:将所有字符串都呈现为 Unicode。正如 Python 的核心开发人员之一布雷特·坎农(Brett Cannon)写道: 人们有时会忘记 Python 诞生的年代。 Guido 于 1989 年 12 月开始对 Python 进行编码,并于 1991 年 2 月首次以开源形式发布。这意味着 Python 本身早于 1991 年 10 月发布的 Unicode 标准的第一版。在随后的几年中,Unicode 标准化后创建的语言选择使用基于 Unicode 编码字符串的实现。 支持任何语言的 Unicode 和文本非常重要。 Python 是一种世界语言,不仅是支持 ASCII 覆盖的罗马字母的语言,这就是 Python 3 在处理文本时将其默认设为“ Unicode”的原因。它保证了所有 Python 3 代码都将支持世界上的每个人,无论编写该代码的开发人员是否明确为其指定 Unicode 编码。 不幸的是,该团队假设每个人都将立即进行大的切换,并使 Python 3 向后不兼容,并将 Python 2 设置为维护分支。但是,许多人不想切换,因为正如改进的 PEP 所说,Python 3 是“相对于 Python 2 的温和的改进。”许多人并没有因为这些带来的不便而切换。当时,Python2、3 最大的区别是将 print 语句更改为 print() 函数语法,这破坏了很多 Python 2 代码。 结果,此后很多年 Python 2 还继续处于积极的开发中。 不过,在 2019 年,Python 3 终于成为了新 Python 软件工程师(大部分)开发的默认语言版本,现在许多公司和项目都在使用 Python 3 的主要功能:f- 字符串、Path、类型提示、异步,当然还包括 Unicode 编码。 缓慢的迭代过程 自从新的版本于 2008 年宣布以来,Python 3 市场份额增长一直很漫长: 最初,有很多理由不采用 Python 3:最重要的是,它与 Python 2 并没有向后兼容。结果导致一些 Python2 的主要库往 Python3 迁移都犹豫不决。2 向 3 转换的转折点发生在大约 2016 年左右的 Python 3.5 发行版中,该版本具有矩阵乘法、asyncio 的引入、OrderedDict 的速度改进以及类型提示的实现,这些提示为 Python3 带来了一些类似于静态语言的实用功能。 Python3 更高版本包含更多功能,例如 Pathlib 库和 f- 字符串操作。通过这些更改,人们使用了许多库(例如用于机器学习的 scikit-learn)开始了向 Python 3 的迁移。 随着越来越多的依赖关系开始升级,一些公司也开始迁移 Python3。 从互联网上的状况来看,您可能以为每个人都完成了 Python3 迁移。 在 Jetbrains 进行的一项调查中,他们制作了 IntelliJ 和 PyCharm 之类的 IDE,有 75%的个人受访者表示他们已经迁移到 Python3。一连串的博客文章都显示了相同的内容,例如,Dropbox 于 2018 年秋季详细说明了他们的迁移 Python3、Instagram 于 2017 年迁移 Python3、Facebook 于 2014 年开始迁移 Python3。在客户的敦促下,Splunk 最近也这样做了 – 往 Python3 迁移。 但是,仅仅因为 Python 2 即将到期,并不意味着公司会在一夜之间停止使用它。我们怎么知道 Python 2 仍在大量的使用?我们可以直接检查 Python 包库 PyPI 的运行情况。2016 年,PyPI 核心开发人员开始将日志发送到 Google 的 BigQuery,以便能够针对它们运行 SQL,这使得根据使用情况做出体系结构决策变得更加容易。 例如,如果要查看过去 30 天内通过 Python 版本下载了哪些库,则可以在 BigQuery 中创建一个新项目(每月查询的前 1TB 是免费的),然后运行: SELECT REGEXP_EXTRACT(details.python, r"^([^\.]+\.[^\.]+)") as python_version, COUNT(*) as download_count, FROM TABLE_DATE_RANGE( [the-psf:pypi.downloads], DATE_ADD(CURRENT_TIMESTAMP(), -31, "day"), DATE_ADD(CURRENT_TIMESTAMP(), -1, "day") ) GROUP BY python_version, ORDER BY download_count DESC LIMIT 100 尽管 Python 3 一直是社区中的主导版本至少一年,但从 PyPI 下载的单个软件包的最新数量显示,2019 年 9 月所有软件包下载中至少有 40%为 2.7 版本。诚然,这比年初的 60%有所下降,但是鉴于 EOL 距离只有数月之遥,所以这个数据仍然很重要。 在每个库的基础上,它变得有些棘手:大多数 Flask 下载都是使用 Python 3 版本完成的,但是只有 26%的 botocore 下载(适用于 Python 的 AWS 开发工具包)正在使用 Python 3。 而且,有几个库需要进行迁移:Twisted 和 PyPy(常用的 JIT 编译器)将无限期保留版本 2。 任何给定软件的寿命终止通常并不意味着该软件不再可用。这确实意味着它不再针对任何安全漏洞或添加任何其他错误修复程序进行更新。但是,不更新到 Python 3 会带来很多风险 - 最重要的是,可能会丢失安全更新,无法利用类型提示和速度提升等新功能。 为什么 Python3 迁移速度这么慢? 开个玩笑,在我写本文的时候,我的 IT 系统还在 Java 8 上运行(按今天的标准,这已经很古老了。但是根据 2018 年的 JVM 生态系统报告,Java 8 仍然是主要的开发环境。) 这就是答案:大多数大型组织,在技术新闻发布的炒作周期之外,其行动要比新闻媒体或博客想像的要慢得多。例如,大多数主要银行仍在运行 FORTRAN 和 COBOL 的编程语言系统。 因此,尽管许多公司描述了他们的迁移策略,但更多的应用软件将长期保留在 Python 2 上。 为什么会这样呢? 在所有决策中,政治发挥的作用和技术指导一样重要 例如,为了在 Facebook 上使用 Python 3,Jason Fried 从 2014 年开始重写 Python3 服务。一路走来,他犯了很多错误,更改了很多代码,并做了很多修改以使其广为人知人们正在做 Facebook 之类的事情,例如参加新的开发人员培训,从而开始使用 Python 3。然后,他与ŁukaszLanga 合作,后者将 Instagram 转换为 Python 3: 2016 年,他和 Langa 在 Facebook 上组建了一个全新的团队,以在公司内部管理 Python3。由于他们是“ Python 团队”,因此他先前提到的“公认权威”起作用。人们认为他们可以在 Facebook 上做出有关 Python 的决定。实际上,Instagram 的迁移项目本身耗时 10 个月。 Guido 和 Langa 现在工作的 Dropbox 花费了三年时间,而直到 Guido 几周前退休为止,它仍在进行中。 诚然,上面这些案例都是巨大的 Python 代码库,但您必须怀疑:如果 Python 的高层人员从事此工作需要花费这么长时间,那么对于一家公司非高层做决策来说可能要花费更多的时间。 安全问题是一个很重要的考量问题 具有讽刺意味的是,您会认为不升级将是更大的风险。但是在较大的组织中,不允许升级 Python3:管理员或安全团队向他们推送更新。在某些情况下,也不允许下载更新 PIP。如果 Python 2 是安全团队同意的默认协议,那么它可能需要做出巨大的努力才能说服人们将其切换到 3,尤其是在受到严格监管(例如医疗保健或金融)和政府的 IT 环境中。 惯性 尽管许多版本的 Linux(例如 RHEL)在 Python 2 和 Python 3 之间都包括了 Python 3,但这绝不是默认值,在 2 和 3 之间切换时,经常发现一些问题,尤其是指向系统版本的链接默认使用 Python2。Python 经历了从 2 到 3 的漫漫长路,个人和具有前瞻性的创业公司都采用了它。现在,第二大迁移将发生在大型企业从 2 开始迁移的时候。关于 Python 2,我们将看到 2020 年 40%使用率的数量进一步减少,但是变化将是递增的。 英文原文

珍宝珠 2020-01-06 10:36:04 0 浏览量 回答数 0

回答

PHP面试干货 1、进程和线程 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于: 简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多线程程序的并发性高。 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。 2、apache默认使用进程管理还是线程管理?如何判断并设置最大连接数? 一个进程可以开多个线程 默认是进程管理 默认有一个主进程 Linux: ps -aux | grep httpd | more 一个子进程代表一个用户的连接 Conf/extra/httpd-mpm.conf 多路功能模块 http -l 查询当前apache处于什么模式下 3、单例模式 单例模式需求:只能实例化产生一个对象 如何实现: 私有化构造函数 禁止克隆对象 提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一对象 需要一个保存类的静态属性 class demo { private static $MyObject; //保存对象的静态属性 private function __construct(){ //私有化构造函数 } private function __clone(){ //禁止克隆 } public static function getInstance(){ if(! (self::$MyObject instanceof self)){ self::$MyObject = new self; } return self::$MyObject; } } 4、安装完Apache后,在http.conf中配置加载PHP文件以Apache模块的方式安装PHP,在文件http.conf中首先要用语句LoadModule php5_module "e:/php/php5apache2.dll"动态装载PHP模块,然后再用语句AddType application/x-httpd-php .php 使得Apache把所有扩展名为PHP的文件都作为PHP脚本处理 5、debug_backtrace()函数能返回脚本里的任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的 function one($str1, $str2) { two("Glenn", "Quagmire"); } function two($str1, $str2) { three("Cleveland", "Brown"); } function three($str1, $str2) { print_r(debug_backtrace()); } one("Peter", "Griffin"); Array ( [0] => Array ( [file] => D:\www\test\result.php [line] => 9 [function] => three [args] => Array ( [0] => Cleveland [1] => Brown ) ) [1] => Array ( [file] => D:\www\test\result.php [line] => 5 [function] => two [args] => Array ( [0] => Glenn [1] => Quagmire ) ) [2] => Array ( [file] => D:\www\test\result.php [line] => 16 [function] => one [args] => Array ( [0] => Peter [1] => Griffin ) ) ) 6、输出用户的IP地址,并且判断用户的IP地址是否在192.168.1.100 — 192.168.1.150之间 echo $ip=getenv('REMOTE_ADDR'); $ip=str_replace('.','',$ip); if($ip<1921681150 && $ip>1921681100) { echo 'ip在192.168.1.100—–192.168.1.150之间'; } else { echo 'ip不在192.168.1.100—–192.168.1.150之间'; } 7、请将2维数组按照name的长度进行重新排序,按照顺序将id赋值 $tarray = array( array('id' => 0, 'name' => '123'), array('id' => 0, 'name' => '1234'), array('id' => 0, 'name' => '1235'), array('id' => 0, 'name' => '12356'), array('id' => 0, 'name' => '123abc') ); foreach($tarray as $key=>$val) { $c[]=$val['name']; } function aa($a,$b) { if(strlen($a)==strlen($b)) return 0; return strlen($a)>strlen($b)?-1:1; } usort($c,'aa'); $len=count($c); for($i=0;$i<$len;$i++) { $t[$i]['id']=$i+1; $t[$i]['name']=$c[$i]; } print_r($t); 8、表单数据提交方式POST和GET的区别,URL地址传递的数据最大长度是多少? POST方式提交数据用户不可见,是数据更安全,最大长度不受限制,而GET方式传值在URL地址可以看到,相对不安全,对大长度是2048字节。 9、SESSION和COOKIE的作用和区别,SESSION信息的存储方式,如何进行遍历 SESSION和COOKIE都能够使值在页面之间进行传递,SESSION存储在服务器端,数据更安全,COOKIE保存在客户端,用户使用手段可以进行修改,SESSION依赖于COOKIE进行传递的。Session遍历使用$_SESSION[]取值,cookie遍历使用$_COOKIE[]取值。 10、什么是数据库索引,主键索引,唯一索引的区别,索引的缺点是什么 索引用来快速地寻找那些具有特定值的记录。 主键索引和唯一索引的区别:主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”,每个表只能有一个主键。唯一索引索引列的所有值都只能出现一次,即必须唯一。 索引的缺点: 1、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 2、索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,需要的空间就会更大。 3、当对表中的数据进行增加、删除、修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 11、数据库设计时,常遇到的性能瓶颈有哪些,常有的解决方案 瓶颈主要有: 1、磁盘搜索 优化方法是:将数据分布在多个磁盘上 2、磁盘读/写 优化方法是:从多个磁盘并行读写。 3、CPU周期 优化方法:扩充内存 4、内存带宽 12、include和require区别 include引入文件的时候,如果碰到错误,会给出提示,并继续运行下边的代码。 require引入文件的时候,如果碰到错误,会给出提示,并停止运行下边的代码。 13、文件上传时设计到点 和文件上传有关的php.ini配置选项(File Uploads): file_uploads=On/Off:文件是否允许上传 upload_max_filesize上传文件时,单个文件的最大大小 post_max_size:提交表单时,整个post表单的最大大小 max_file_uploads =20上传文件的个数 内存占用,脚本最大执行时间也间接影响到文件的上传 14、header常见状态 //200 正常状态 header('HTTP/1.1 200 OK'); // 301 永久重定向,记得在后面要加重定向地址 Location:$url header('HTTP/1.1 301 Moved Permanently'); // 重定向,其实就是302 暂时重定向 header('Location: http://www.maiyoule.com/'); // 设置页面304 没有修改 header('HTTP/1.1 304 Not Modified'); // 显示登录框, header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Basic realm="登录信息"'); echo '显示的信息!'; // 403 禁止访问 header('HTTP/1.1 403 Forbidden'); // 404 错误 header('HTTP/1.1 404 Not Found'); // 500 服务器错误 header('HTTP/1.1 500 Internal Server Error'); // 3秒后重定向指定地址(也就是刷新到新页面与 <meta http-equiv="refresh" content="10;http://www.maiyoule.com/ /> 相同) header('Refresh: 3; url=http://www.maiyoule.com/'); echo '10后跳转到http://www.maiyoule.com'; // 重写 X-Powered-By 值 header('X-Powered-By: PHP/5.3.0'); header('X-Powered-By: Brain/0.6b'); //设置上下文语言 header('Content-language: en'); // 设置页面最后修改时间(多用于防缓存) $time = time() - 60; //建议使用filetime函数来设置页面缓存时间 header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT'); // 设置内容长度 header('Content-Length: 39344'); // 设置头文件类型,可以用于流文件或者文件下载 header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="example.zip"'); header('Content-Transfer-Encoding: binary'); readfile('example.zip');//读取文件到客户端 //禁用页面缓存 header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Pragma: no-cache'); //设置页面头信息 header('Content-Type: text/html; charset=iso-8859-1'); header('Content-Type: text/html; charset=utf-8'); header('Content-Type: text/plain'); header('Content-Type: image/jpeg'); header('Content-Type: application/zip'); header('Content-Type: application/pdf'); header('Content-Type: audio/mpeg'); header('Content-Type: application/x-shockwave-flash'); //.... 至于Content-Type 的值 可以去查查 w3c 的文档库,那里很丰富 15、ORM和ActiveRecord ORM:object relation mapping,即对象关系映射,简单的说就是对象模型和关系模型的一种映射。为什么要有这么一个映射?很简单,因为现在的开发语言基本都是oop的,但是传统的数据库却是关系型的。为了可以靠贴近面向对象开发,我们想要像操作对象一样操作数据库。还可以隔离底层数据库层,我们不需要关心我们使用的是mysql还是其他的关系型数据库 ActiveRecord也属于ORM层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。 ActiveRecord的主要思想是: 1. 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的Field; 2. ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;; 3. ActiveRecord是一种领域模型(Domain Model),封装了部分业务逻辑; ActiveRecord比较适用于: 1. 业务逻辑比较简单,当你的类基本上和数据库中的表一一对应时, ActiveRecord是非常方便的,即你的业务逻辑大多数是对单表操作; 2. 当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script),把跨表事务提升到事务脚本中; 3. ActiveRecord最大优点是简单, 直观。 一个类就包括了数据访问和业务逻辑. 如果配合代码生成器使用就更方便了; 这些优点使ActiveRecord特别适合WEB快速开发。 16、斐波那契方法,也就是1 1 2 3 5 8 ……,这里给出两种方法,大家可以对比下,看看哪种快,以及为什么 function fibonacci($n){ if($n == 0){ return 0; } if($n == 1){ return 1; } return fibonacci($n-1)+fibonacci($n-2); } function fibonacci($n){ for($i=0; $i<$n; $i++){ $r[] = $i<2 ? 1 : $r[$i-1]+$r[$i-2]; } return $r[--$i]; } 17、约瑟夫环,也就是常见的数猴子,n只猴子围成一圈,每只猴子下面标了编号,从1开始数起,数到m那么第m只猴子便退出,依次类推,每数到m,那么那个位置的猴子退出,那么最后剩下的猴子下的编号是啥。 function yuesefu($n,$m) { $r=0; for($i=2; $i<=$n; $i++) { $r=($r+$m)%$i; } return $r+1; } 18、冒泡排序,大致是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束 function bubbleSort($arr){ for($i=0, $len=count($arr); $i<$len; $i++){ for($j=0; $j<$len; $j++){ if($arr[$i]<$arr[$j]){ $tmp = $arr[$j]; $arr[$j] = $arr[$i]; $arr[$i] = $tmp; } } } return $arr; } 19、快速排序,也就是找出一个元素(理论上可以随便找一个)作为基准,然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。 function quickSort($arr){ $len = count($arr); if($len <=1){ return $arr; } $key = $arr[0]; $leftArr = $rightArr= array(); for($i=1; $i<$len; $i++){ if($arr[$i] <= $key){ $leftArr[] = $arr[$i]; } else{ $rightArr[] = $arr[$i]; } } $leftArr = quickSort($leftArr); $rightArr = quickSort($rightArr); return array_merge($leftArr, array($key), $rightArr); } 20、(递归的)列出目录下所有文件及目录,这里也有两种方法 function listDir($path){ $res = dir($path); while($file = $res->read()){ if($file == '.' || $file == '..'){ continue; } if(is_dir($path . '/' .$file)){ echo $path . '/' .$file . "\r\n"; listDir($path . '/' .$file); } else{ echo $path . '/' .$file . "\r\n"; } } $res->close(); } function listDir($path){ if(is_dir($path)){ if(FALSE !== ($res = opendir($path))){ while(FALSE !== ($file = readdir($res))){ if($file == '.' || $file == '..'){ continue; } $subPath = $path . '/' . $file; if(is_dir($subPath)){ echo $subPath . "\r\n"; listDir($subPath); } else{ echo $subPath . "\r\n"; } } } } } 21、找出相对的目录,比如/a/b/c/d/e.php相对于/a/b/13/34/c.php是/c/d/ function ralativePath($a, $b){ $a = explode('/', dirname($a)); $b = explode('/', dirname($b)); $c = '/'; foreach ($a as $k=> $v){ if($v != $b[$k]){ $c .= $v . '/'; } } echo $c; } 22、快速找出url中php后缀 function get_ext($url){ $data = parse_url($url); return pathinfo($data['path'], PATHINFO_EXTENSION); } 23、正则题,使用正则抓取网页,以网页meta为utf8为准,若是抓取的网页编码为big5之类的,需要转化为utf8再收录 function preg_meta($meta){ $replacement = "\\1utf8\\6\\7"; $pattern = '#(<meta\s+http-equiv=(\'|"|)Content-Type(\'|"|)\s+content=(\'|"|)text/html; charset=)(\w+)(\'|"|)(>)#i'; return preg_replace($pattern, $replacement, $meta); } echo preg_meta("<meta http-equiv=Content-Type content='text/html; charset=big5'><META http-equiv=\"Content-Type\" content='text/html; charset=big5'>"); 24、不用php的反转函数倒序输出字符串,如abc,反序输出cba function revstring($str){ for($i=strlen($str)-1; $i>=0; $i--){ echo $str{$i}; } } revstring('abc'); 25、常见端口 TCP 21端口:FTP 文件传输服务 SSH 22端口:SSH连接linux服务器,通过SSH连接可以远程管理Linux等设备 TCP 23端口:TELNET 终端仿真服务 TCP 25端口:SMTP 简单邮件传输服务 UDP 53端口:DNS 域名解析服务 TCP 80端口:HTTP 超文本传输服务 TCP 110端口:POP3 “邮局协议版本3”使用的端口 TCP 443端口:HTTPS 加密的超文本传输服务 TCP 1521端口:Oracle数据库服务 TCP 1863端口:MSN Messenger的文件传输功能所使用的端口 TCP 3389端口:Microsoft RDP 微软远程桌面使用的端口 TCP 5631端口:Symantec pcAnywhere 远程控制数据传输时使用的端口 UDP 5632端口:Symantec pcAnywhere 主控端扫描被控端时使用的端口 TCP 5000端口:MS SQL Server使用的端口 UDP 8000端口:腾讯QQ 26、linux常用的命令 top linux进程实时监控 ps 在Linux中是查看进程的命令。ps查看正处于Running的进程 mv 为文件或目录改名或将文件由一个目录移入另一个目录中。 find 查找文件 df 可显示所有文件系统对i节点和磁盘块的使用情况。 cat 打印文件类容 chmod 变更文件或目录的权限 chgrp 文件或目录的权限的掌控以拥有者及所诉群组来管理。可以使用chgrp指令取变更文件与目录所属群组 grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。 wc 为统计指定文件中的字节数、字数、行数,并将统计结果显示输出 27、对于大流量的网站,您采用什么样的方法来解决访问量问题 首先,确认服务器硬件是否足够支持当前的流量 其次,优化数据库访问。 第三,禁止外部的盗链。 第四,控制大文件的下载。 第五,使用不同主机分流主要流量 第六,使用流量分析统计软件 28、$_SERVER常用的字段 $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名 $_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称 $_SERVER['REQUEST_METHOD'] #访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT” $_SERVER['QUERY_STRING'] #查询(query)的字符串 $_SERVER['HTTP_HOST'] #当前请求的 Host: 头部的内容 $_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址 $_SERVER['REMOTE_ADDR'] #正在浏览当前页面用户的 IP 地址 $_SERVER['REMOTE_HOST'] #正在浏览当前页面用户的主机名 $_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名 $_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用 $_SERVER['REQUEST_URI'] #访问此页面所需的 URI。例如,“/index.html” 29、安装php扩展 进入扩展的目录 phpize命令得到configure文件 ./configure --with-php-config=/usr/local/php/bin/php-config make & make install 在php.ini中加入扩展名称.so 重启web服务器(nginx/apache) 30、php-fpm与nginx PHP-FPM也是一个第三方的FastCGI进程管理器,它是作为PHP的一个补丁来开发的,在安装的时候也需要和PHP源码一起编译,也就是说PHP-FPM被编译到PHP内核中,因此在处理性能方面更加优秀;同时它在处理高并发方面也比spawn-fcgi引擎好很多,因此,推荐Nginx+PHP/PHP-FPM这个组合对PHP进行解析。 FastCGI 的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求 #fastcgi FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同时,FastCGI也被许多脚本语言所支持,其中就有PHP。 FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。 FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。 Nginx+FastCGI运行原理 Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端,这就是Nginx+FastCGI的整个运作过程。 31、ajax全称“Asynchronous Javascript And XML”(异步JavaScript和XML)

小川游鱼 2019-12-02 01:41:29 0 浏览量 回答数 0

回答

PHP面试干货 1、进程和线程 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于: 简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多线程程序的并发性高。 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。 2、apache默认使用进程管理还是线程管理?如何判断并设置最大连接数? 一个进程可以开多个线程 默认是进程管理 默认有一个主进程 Linux: ps -aux | grep httpd | more 一个子进程代表一个用户的连接 Conf/extra/httpd-mpm.conf 多路功能模块 http -l 查询当前apache处于什么模式下 3、单例模式 单例模式需求:只能实例化产生一个对象 如何实现: 私有化构造函数 禁止克隆对象 提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一对象 需要一个保存类的静态属性 class demo { private static $MyObject; //保存对象的静态属性 private function __construct(){ //私有化构造函数 } private function __clone(){ //禁止克隆 } public static function getInstance(){ if(! (self::$MyObject instanceof self)){ self::$MyObject = new self; } return self::$MyObject; } } 4、安装完Apache后,在http.conf中配置加载PHP文件以Apache模块的方式安装PHP,在文件http.conf中首先要用语句LoadModule php5_module "e:/php/php5apache2.dll"动态装载PHP模块,然后再用语句AddType application/x-httpd-php .php 使得Apache把所有扩展名为PHP的文件都作为PHP脚本处理 5、debug_backtrace()函数能返回脚本里的任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的 function one($str1, $str2) { two("Glenn", "Quagmire"); } function two($str1, $str2) { three("Cleveland", "Brown"); } function three($str1, $str2) { print_r(debug_backtrace()); } one("Peter", "Griffin"); Array ( [0] => Array ( [file] => D:\www\test\result.php [line] => 9 [function] => three [args] => Array ( [0] => Cleveland [1] => Brown ) ) [1] => Array ( [file] => D:\www\test\result.php [line] => 5 [function] => two [args] => Array ( [0] => Glenn [1] => Quagmire ) ) [2] => Array ( [file] => D:\www\test\result.php [line] => 16 [function] => one [args] => Array ( [0] => Peter [1] => Griffin ) ) ) 6、输出用户的IP地址,并且判断用户的IP地址是否在192.168.1.100 — 192.168.1.150之间 echo $ip=getenv('REMOTE_ADDR'); $ip=str_replace('.','',$ip); if($ip<1921681150 && $ip>1921681100) { echo 'ip在192.168.1.100—–192.168.1.150之间'; } else { echo 'ip不在192.168.1.100—–192.168.1.150之间'; } 7、请将2维数组按照name的长度进行重新排序,按照顺序将id赋值 $tarray = array( array('id' => 0, 'name' => '123'), array('id' => 0, 'name' => '1234'), array('id' => 0, 'name' => '1235'), array('id' => 0, 'name' => '12356'), array('id' => 0, 'name' => '123abc') ); foreach($tarray as $key=>$val) { $c[]=$val['name']; } function aa($a,$b) { if(strlen($a)==strlen($b)) return 0; return strlen($a)>strlen($b)?-1:1; } usort($c,'aa'); $len=count($c); for($i=0;$i<$len;$i++) { $t[$i]['id']=$i+1; $t[$i]['name']=$c[$i]; } print_r($t); 8、表单数据提交方式POST和GET的区别,URL地址传递的数据最大长度是多少? POST方式提交数据用户不可见,是数据更安全,最大长度不受限制,而GET方式传值在URL地址可以看到,相对不安全,对大长度是2048字节。 9、SESSION和COOKIE的作用和区别,SESSION信息的存储方式,如何进行遍历 SESSION和COOKIE都能够使值在页面之间进行传递,SESSION存储在服务器端,数据更安全,COOKIE保存在客户端,用户使用手段可以进行修改,SESSION依赖于COOKIE进行传递的。Session遍历使用$_SESSION[]取值,cookie遍历使用$_COOKIE[]取值。 10、什么是数据库索引,主键索引,唯一索引的区别,索引的缺点是什么 索引用来快速地寻找那些具有特定值的记录。 主键索引和唯一索引的区别:主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”,每个表只能有一个主键。唯一索引索引列的所有值都只能出现一次,即必须唯一。 索引的缺点: 1、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 2、索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,需要的空间就会更大。 3、当对表中的数据进行增加、删除、修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 11、数据库设计时,常遇到的性能瓶颈有哪些,常有的解决方案 瓶颈主要有: 1、磁盘搜索 优化方法是:将数据分布在多个磁盘上 2、磁盘读/写 优化方法是:从多个磁盘并行读写。 3、CPU周期 优化方法:扩充内存 4、内存带宽 12、include和require区别 include引入文件的时候,如果碰到错误,会给出提示,并继续运行下边的代码。 require引入文件的时候,如果碰到错误,会给出提示,并停止运行下边的代码。 13、文件上传时设计到点 和文件上传有关的php.ini配置选项(File Uploads): file_uploads=On/Off:文件是否允许上传 upload_max_filesize上传文件时,单个文件的最大大小 post_max_size:提交表单时,整个post表单的最大大小 max_file_uploads =20上传文件的个数 内存占用,脚本最大执行时间也间接影响到文件的上传 14、header常见状态 //200 正常状态 header('HTTP/1.1 200 OK'); // 301 永久重定向,记得在后面要加重定向地址 Location:$url header('HTTP/1.1 301 Moved Permanently'); // 重定向,其实就是302 暂时重定向 header('Location: http://www.maiyoule.com/'); // 设置页面304 没有修改 header('HTTP/1.1 304 Not Modified'); // 显示登录框, header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Basic realm="登录信息"'); echo '显示的信息!'; // 403 禁止访问 header('HTTP/1.1 403 Forbidden'); // 404 错误 header('HTTP/1.1 404 Not Found'); // 500 服务器错误 header('HTTP/1.1 500 Internal Server Error'); // 3秒后重定向指定地址(也就是刷新到新页面与 <meta http-equiv="refresh" content="10;http://www.maiyoule.com/ /> 相同) header('Refresh: 3; url=http://www.maiyoule.com/'); echo '10后跳转到http://www.maiyoule.com'; // 重写 X-Powered-By 值 header('X-Powered-By: PHP/5.3.0'); header('X-Powered-By: Brain/0.6b'); //设置上下文语言 header('Content-language: en'); // 设置页面最后修改时间(多用于防缓存) $time = time() - 60; //建议使用filetime函数来设置页面缓存时间 header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT'); // 设置内容长度 header('Content-Length: 39344'); // 设置头文件类型,可以用于流文件或者文件下载 header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="example.zip"'); header('Content-Transfer-Encoding: binary'); readfile('example.zip');//读取文件到客户端 //禁用页面缓存 header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Pragma: no-cache'); //设置页面头信息 header('Content-Type: text/html; charset=iso-8859-1'); header('Content-Type: text/html; charset=utf-8'); header('Content-Type: text/plain'); header('Content-Type: image/jpeg'); header('Content-Type: application/zip'); header('Content-Type: application/pdf'); header('Content-Type: audio/mpeg'); header('Content-Type: application/x-shockwave-flash'); //.... 至于Content-Type 的值 可以去查查 w3c 的文档库,那里很丰富 15、ORM和ActiveRecord ORM:object relation mapping,即对象关系映射,简单的说就是对象模型和关系模型的一种映射。为什么要有这么一个映射?很简单,因为现在的开发语言基本都是oop的,但是传统的数据库却是关系型的。为了可以靠贴近面向对象开发,我们想要像操作对象一样操作数据库。还可以隔离底层数据库层,我们不需要关心我们使用的是mysql还是其他的关系型数据库 ActiveRecord也属于ORM层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。 ActiveRecord的主要思想是: 1. 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的Field; 2. ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;; 3. ActiveRecord是一种领域模型(Domain Model),封装了部分业务逻辑; ActiveRecord比较适用于: 1. 业务逻辑比较简单,当你的类基本上和数据库中的表一一对应时, ActiveRecord是非常方便的,即你的业务逻辑大多数是对单表操作; 2. 当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script),把跨表事务提升到事务脚本中; 3. ActiveRecord最大优点是简单, 直观。 一个类就包括了数据访问和业务逻辑. 如果配合代码生成器使用就更方便了; 这些优点使ActiveRecord特别适合WEB快速开发。 16、斐波那契方法,也就是1 1 2 3 5 8 ……,这里给出两种方法,大家可以对比下,看看哪种快,以及为什么 function fibonacci($n){ if($n == 0){ return 0; } if($n == 1){ return 1; } return fibonacci($n-1)+fibonacci($n-2); } function fibonacci($n){ for($i=0; $i<$n; $i++){ $r[] = $i<2 ? 1 : $r[$i-1]+$r[$i-2]; } return $r[--$i]; } 17、约瑟夫环,也就是常见的数猴子,n只猴子围成一圈,每只猴子下面标了编号,从1开始数起,数到m那么第m只猴子便退出,依次类推,每数到m,那么那个位置的猴子退出,那么最后剩下的猴子下的编号是啥。 function yuesefu($n,$m) { $r=0; for($i=2; $i<=$n; $i++) { $r=($r+$m)%$i; } return $r+1; } 18、冒泡排序,大致是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束 function bubbleSort($arr){ for($i=0, $len=count($arr); $i<$len; $i++){ for($j=0; $j<$len; $j++){ if($arr[$i]<$arr[$j]){ $tmp = $arr[$j]; $arr[$j] = $arr[$i]; $arr[$i] = $tmp; } } } return $arr; } 19、快速排序,也就是找出一个元素(理论上可以随便找一个)作为基准,然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。 function quickSort($arr){ $len = count($arr); if($len <=1){ return $arr; } $key = $arr[0]; $leftArr = $rightArr= array(); for($i=1; $i<$len; $i++){ if($arr[$i] <= $key){ $leftArr[] = $arr[$i]; } else{ $rightArr[] = $arr[$i]; } } $leftArr = quickSort($leftArr); $rightArr = quickSort($rightArr); return array_merge($leftArr, array($key), $rightArr); } 20、(递归的)列出目录下所有文件及目录,这里也有两种方法 function listDir($path){ $res = dir($path); while($file = $res->read()){ if($file == '.' || $file == '..'){ continue; } if(is_dir($path . '/' .$file)){ echo $path . '/' .$file . "\r\n"; listDir($path . '/' .$file); } else{ echo $path . '/' .$file . "\r\n"; } } $res->close(); } function listDir($path){ if(is_dir($path)){ if(FALSE !== ($res = opendir($path))){ while(FALSE !== ($file = readdir($res))){ if($file == '.' || $file == '..'){ continue; } $subPath = $path . '/' . $file; if(is_dir($subPath)){ echo $subPath . "\r\n"; listDir($subPath); } else{ echo $subPath . "\r\n"; } } } } } 21、找出相对的目录,比如/a/b/c/d/e.php相对于/a/b/13/34/c.php是/c/d/ function ralativePath($a, $b){ $a = explode('/', dirname($a)); $b = explode('/', dirname($b)); $c = '/'; foreach ($a as $k=> $v){ if($v != $b[$k]){ $c .= $v . '/'; } } echo $c; } 22、快速找出url中php后缀 function get_ext($url){ $data = parse_url($url); return pathinfo($data['path'], PATHINFO_EXTENSION); } 23、正则题,使用正则抓取网页,以网页meta为utf8为准,若是抓取的网页编码为big5之类的,需要转化为utf8再收录 function preg_meta($meta){ $replacement = "\\1utf8\\6\\7"; $pattern = '#(<meta\s+http-equiv=(\'|"|)Content-Type(\'|"|)\s+content=(\'|"|)text/html; charset=)(\w+)(\'|"|)(>)#i'; return preg_replace($pattern, $replacement, $meta); } echo preg_meta("<meta http-equiv=Content-Type content='text/html; charset=big5'><META http-equiv=\"Content-Type\" content='text/html; charset=big5'>"); 24、不用php的反转函数倒序输出字符串,如abc,反序输出cba function revstring($str){ for($i=strlen($str)-1; $i>=0; $i--){ echo $str{$i}; } } revstring('abc'); 25、常见端口 TCP 21端口:FTP 文件传输服务 SSH 22端口:SSH连接linux服务器,通过SSH连接可以远程管理Linux等设备 TCP 23端口:TELNET 终端仿真服务 TCP 25端口:SMTP 简单邮件传输服务 UDP 53端口:DNS 域名解析服务 TCP 80端口:HTTP 超文本传输服务 TCP 110端口:POP3 “邮局协议版本3”使用的端口 TCP 443端口:HTTPS 加密的超文本传输服务 TCP 1521端口:Oracle数据库服务 TCP 1863端口:MSN Messenger的文件传输功能所使用的端口 TCP 3389端口:Microsoft RDP 微软远程桌面使用的端口 TCP 5631端口:Symantec pcAnywhere 远程控制数据传输时使用的端口 UDP 5632端口:Symantec pcAnywhere 主控端扫描被控端时使用的端口 TCP 5000端口:MS SQL Server使用的端口 UDP 8000端口:腾讯QQ 26、linux常用的命令 top linux进程实时监控 ps 在Linux中是查看进程的命令。ps查看正处于Running的进程 mv 为文件或目录改名或将文件由一个目录移入另一个目录中。 find 查找文件 df 可显示所有文件系统对i节点和磁盘块的使用情况。 cat 打印文件类容 chmod 变更文件或目录的权限 chgrp 文件或目录的权限的掌控以拥有者及所诉群组来管理。可以使用chgrp指令取变更文件与目录所属群组 grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。 wc 为统计指定文件中的字节数、字数、行数,并将统计结果显示输出 27、对于大流量的网站,您采用什么样的方法来解决访问量问题 首先,确认服务器硬件是否足够支持当前的流量 其次,优化数据库访问。 第三,禁止外部的盗链。 第四,控制大文件的下载。 第五,使用不同主机分流主要流量 第六,使用流量分析统计软件 28、$_SERVER常用的字段 $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名 $_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称 $_SERVER['REQUEST_METHOD'] #访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT” $_SERVER['QUERY_STRING'] #查询(query)的字符串 $_SERVER['HTTP_HOST'] #当前请求的 Host: 头部的内容 $_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址 $_SERVER['REMOTE_ADDR'] #正在浏览当前页面用户的 IP 地址 $_SERVER['REMOTE_HOST'] #正在浏览当前页面用户的主机名 $_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名 $_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用 $_SERVER['REQUEST_URI'] #访问此页面所需的 URI。例如,“/index.html” 29、安装php扩展 进入扩展的目录 phpize命令得到configure文件 ./configure --with-php-config=/usr/local/php/bin/php-config make & make install 在php.ini中加入扩展名称.so 重启web服务器(nginx/apache) 30、php-fpm与nginx PHP-FPM也是一个第三方的FastCGI进程管理器,它是作为PHP的一个补丁来开发的,在安装的时候也需要和PHP源码一起编译,也就是说PHP-FPM被编译到PHP内核中,因此在处理性能方面更加优秀;同时它在处理高并发方面也比spawn-fcgi引擎好很多,因此,推荐Nginx+PHP/PHP-FPM这个组合对PHP进行解析。 FastCGI 的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求 #fastcgi FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同时,FastCGI也被许多脚本语言所支持,其中就有PHP。 FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。 FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。 Nginx+FastCGI运行原理 Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端,这就是Nginx+FastCGI的整个运作过程。 31、ajax全称“Asynchronous Javascript And XML”(异步JavaScript和XML)

小川游鱼 2019-12-02 01:41:29 0 浏览量 回答数 0

回答

共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE 排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE 锁的类别有两种分法: 1. 从数据库系统的角度来看:分为独占锁(即排它锁),共享锁和更新锁 MS-SQL Server 使用以下资源锁模式。 锁模式 描述 共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。 更新 (U) 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。 排它 (X) 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。 意向锁 用于建立锁的层次结构。意向锁的类型为:意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。 架构锁 在执行依赖于表架构的操作时使用。架构锁的类型为:架构修改 (Sch-M) 和架构稳定性 (Sch-S)。 大容量更新 (BU) 向表中大容量复制数据并指定了 TABLOCK 提示时使用。 共享锁 共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。一旦已经读取数据,便立即释放资源上的共享 (S) 锁,除非将事务隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享 (S) 锁。 更新锁 更新 (U) 锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此操作要求锁转换为排它 (X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。 若要避免这种潜在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。 排它锁 排它 (X) 锁可以防止并发事务对资源进行访问。其它事务不能读取或修改排它 (X) 锁锁定的数据。 意向锁 意向锁表示 SQL Server 需要在层次结构中的某些底层资源上获取共享 (S) 锁或排它 (X) 锁。例如,放置在表级的共享意向锁表示事务打算在表中的页或行上放置共享 (S) 锁。在表级设置意向锁可防止另一个事务随后在包含那一页的表上获取排它 (X) 锁。意向锁可以提高性能,因为 SQL Server 仅在表级检查意向锁来确定事务是否可以安全地获取该表上的锁。而无须检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。 意向锁包括意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。 锁模式 描述 意向共享 (IS) 通过在各资源上放置 S 锁,表明事务的意向是读取层次结构中的部分(而不是全部)底层资源。 意向排它 (IX) 通过在各资源上放置 X 锁,表明事务的意向是修改层次结构中的部分(而不是全部)底层资源。IX 是 IS 的超集。 与意向排它共享 (SIX) 通过在各资源上放置 IX 锁,表明事务的意向是读取层次结构中的全部底层资源并修改部分(而不是全部)底层资源。允许顶层资源上的并发 IS 锁。例如,表的 SIX 锁在表上放置一个 SIX 锁(允许并发 IS 锁),在当前所修改页上放置 IX 锁(在已修改行上放置 X 锁)。虽然每个资源在一段时间内只能有一个 SIX 锁,以防止其它事务对资源进行更新,但是其它事务可以通过获取表级的 IS 锁来读取层次结构中的底层资源。 独占锁:只允许进行锁定操作的程序使用,其他任何对他的操作均不会被接受。执行数据更新命令时,SQL Server会自动使用独占锁。当对象上有其他锁存在时,无法对其加独占锁。 共享锁:共享锁锁定的资源可以被其他用户读取,但其他用户无法修改它,在执行Select时,SQL Server会对对象加共享锁。 更新锁:当SQL Server准备更新数据时,它首先对数据对象作更新锁锁定,这样数据将不能被修改,但可以读取。等到SQL Server确定要进行更新数据操作时,他会自动将更新锁换为独占锁,当对象上有其他锁存在时,无法对其加更新锁。 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外。MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。MySQL各存储引擎使用了三种类型(级别)的锁定机制:表级锁定,行级锁定和页级锁定。 1.表级锁定(table-level) 表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。 当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度大打折扣。 使用表级锁定的主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎。 2.行级锁定(row-level) 行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。 虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。 使用行级锁定的主要是InnoDB存储引擎。 3.页级锁定(page-level) 页级锁定是MySQL中比较独特的一种锁定级别,在其他数据库管理软件中也并不是太常见。页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。 在数据库实现资源锁定的过程中,随着锁定资源颗粒度的减小,锁定相同数据量的数据所需要消耗的内存数量是越来越多的,实现算法也会越来越复杂。不过,随着锁定资源颗粒度的减小,应用程序的访问请求遇到锁等待的可能性也会随之降低,系统整体并发度也随之提升。 使用页级锁定的主要是BerkeleyDB存储引擎。 总的来说,MySQL这3种锁的特性可大致归纳如下: 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低; 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高; 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。 适用:从锁的角度来说,表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。 -------------MYSQL处理------------------ 表级锁定 由于MyISAM存储引擎使用的锁定机制完全是由MySQL提供的表级锁定实现,所以下面我们将以MyISAM存储引擎作为示例存储引擎。 1.MySQL表级锁的锁模式 MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。锁模式的兼容性: 对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求; 对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作; MyISAM表的读操作与写操作之间,以及写操作之间是串行的。当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。 2.如何加表锁 MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。 3.MyISAM表锁优化建议 对于MyISAM存储引擎,虽然使用表级锁定在锁定实现的过程中比实现行级锁定或者页级锁所带来的附加成本都要小,锁定本身所消耗的资源也是最少。但是由于锁定的颗粒度比较到,所以造成锁定资源的争用情况也会比其他的锁定级别都要多,从而在较大程度上会降低并发处理能力。所以,在优化MyISAM存储引擎锁定问题的时候,最关键的就是如何让其提高并发度。由于锁定级别是不可能改变的了,所以我们首先需要尽可能让锁定的时间变短,然后就是让可能并发进行的操作尽可能的并发。 (1)查询表级锁争用情况 MySQL内部有两组专门的状态变量记录系统内部锁资源争用情况: mysql> show status like 'table%'; +----------------------------+---------+ | Variable_name | Value | +----------------------------+---------+ | Table_locks_immediate | 100 | | Table_locks_waited | 10 | +----------------------------+---------+ 这里有两个状态变量记录MySQL内部表级锁定的情况,两个变量说明如下: Table_locks_immediate:产生表级锁定的次数; Table_locks_waited:出现表级锁定争用而发生等待的次数; 两个状态值都是从系统启动后开始记录,出现一次对应的事件则数量加1。如果这里的Table_locks_waited状态值比较高,那么说明系统中表级锁定争用现象比较严重,就需要进一步分析为什么会有较多的锁定资源争用了。 (2)缩短锁定时间 如何让锁定时间尽可能的短呢?唯一的办法就是让我们的Query执行时间尽可能的短。 a)尽两减少大的复杂Query,将复杂Query分拆成几个小的Query分布进行; b)尽可能的建立足够高效的索引,让数据检索更迅速; c)尽量让MyISAM存储引擎的表只存放必要的信息,控制字段类型; d)利用合适的机会优化MyISAM表数据文件。 (3)分离能并行的操作 说到MyISAM的表锁,而且是读写互相阻塞的表锁,可能有些人会认为在MyISAM存储引擎的表上就只能是完全的串行化,没办法再并行了。大家不要忘记了,MyISAM的存储引擎还有一个非常有用的特性,那就是ConcurrentInsert(并发插入)的特性。 MyISAM存储引擎有一个控制是否打开Concurrent Insert功能的参数选项:concurrent_insert,可以设置为0,1或者2。三个值的具体说明如下: concurrent_insert=2,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录; concurrent_insert=1,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置; concurrent_insert=0,不允许并发插入。 可以利用MyISAM存储引擎的并发插入特性,来解决应用中对同一表查询和插入的锁争用。例如,将concurrent_insert系统变量设为2,总是允许并发插入;同时,通过定期在系统空闲时段执行OPTIMIZE TABLE语句来整理空间碎片,收回因删除记录而产生的中间空洞。 (4)合理利用读写优先级 MyISAM存储引擎的是读写互相阻塞的,那么,一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢? 答案是写进程先获得锁。不仅如此,即使读请求先到锁等待队列,写请求后到,写锁也会插到读锁请求之前。 这是因为MySQL的表级锁定对于读和写是有不同优先级设定的,默认情况下是写优先级要大于读优先级。 所以,如果我们可以根据各自系统环境的差异决定读与写的优先级: 通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接读比写的优先级高。如果我们的系统是一个以读为主,可以设置此参数,如果以写为主,则不用设置; 通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。 虽然上面方法都是要么更新优先,要么查询优先的方法,但还是可以用其来解决查询相对重要的应用(如用户登录系统)中,读锁等待严重的问题。 另外,MySQL也提供了一种折中的办法来调节读写冲突,即给系统参数max_write_lock_count设置一个合适的值,当一个表的读锁达到这个值后,MySQL就暂时将写请求的优先级降低,给读进程一定获得锁的机会。 这里还要强调一点:一些需要长时间运行的查询操作,也会使写进程“饿死”,因此,应用中应尽量避免出现长时间运行的查询操作,不要总想用一条SELECT语句来解决问题,因为这种看似巧妙的SQL语句,往往比较复杂,执行时间较长,在可能的情况下可以通过使用中间表等措施对SQL语句做一定的“分解”,使每一步查询都能在较短时间完成,从而减少锁冲突。如果复杂查询不可避免,应尽量安排在数据库空闲时段执行,比如一些定期统计可以安排在夜间执行 三、行级锁定 行级锁定不是MySQL自己实现的锁定方式,而是由其他存储引擎自己所实现的,如广为大家所知的InnoDB存储引擎,以及MySQL的分布式存储引擎NDBCluster等都是实现了行级锁定。考虑到行级锁定君由各个存储引擎自行实现,而且具体实现也各有差别,而InnoDB是目前事务型存储引擎中使用最为广泛的存储引擎,所以这里我们就主要分析一下InnoDB的锁定特性。 1.InnoDB锁定模式及实现机制 考虑到行级锁定君由各个存储引擎自行实现,而且具体实现也各有差别,而InnoDB是目前事务型存储引擎中使用最为广泛的存储引擎,所以这里我们就主要分析一下InnoDB的锁定特性。 总的来说,InnoDB的锁定机制和Oracle数据库有不少相似之处。InnoDB的行级锁定同样分为两种类型,共享锁和排他锁,而在锁定机制的实现过程中为了让行级锁定和表级锁定共存,InnoDB也同样使用了意向锁(表级锁定)的概念,也就有了意向共享锁和意向排他锁这两种。 当一个事务需要给自己需要的某个资源加锁的时候,如果遇到一个共享锁正锁定着自己需要的资源的时候,自己可以再加一个共享锁,不过不能加排他锁。但是,如果遇到自己需要锁定的资源已经被一个排他锁占有之后,则只能等待该锁定释放资源之后自己才能获取锁定资源并添加自己的锁定。而意向锁的作用就是当一个事务在需要获取资源锁定的时候,如果遇到自己需要的资源已经被排他锁占用的时候,该事务可以需要锁定行的表上面添加一个合适的意向锁。如果自己需要一个共享锁,那么就在表上面添加一个意向共享锁。而如果自己需要的是某行(或者某些行)上面添加一个排他锁的话,则先在表上面添加一个意向排他锁。意向共享锁可以同时并存多个,但是意向排他锁同时只能有一个存在。所以,可以说InnoDB的锁定模式实际上可以分为四种:共享锁(S),排他锁(X),意向共享锁(IS)和意向排他锁(IX),我们可以通过以下表格来总结上面这四种所的共存逻辑关系 如果一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。 意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁;事务可以通过以下语句显示给记录集加共享锁或排他锁。 共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE 排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE 用SELECT ... IN SHARE MODE获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。 但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT... FOR UPDATE方式获得排他锁。 2.InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁 在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。下面通过一些实际例子来加以说明。 (1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁。 (2)由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。 (3)当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。 (4)即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。 3.间隙锁(Next-Key锁) 当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁; 对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。 例: 假如emp表中只有101条记录,其empid的值分别是 1,2,...,100,101,下面的SQL: mysql> select * from emp where empid > 100 for update; 是一个范围条件的检索,InnoDB不仅会对符合条件的empid值为101的记录加锁,也会对empid大于101(这些记录并不存在)的“间隙”加锁。 InnoDB使用间隙锁的目的: (1)防止幻读,以满足相关隔离级别的要求。对于上面的例子,要是不使用间隙锁,如果其他事务插入了empid大于100的任何记录,那么本事务如果再次执行上述语句,就会发生幻读; (2)为了满足其恢复和复制的需要。 很显然,在使用范围条件检索并锁定记录时,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下这可能会对性能造成很大的危害。 除了间隙锁给InnoDB带来性能的负面影响之外,通过索引实现锁定的方式还存在其他几个较大的性能隐患: (1)当Query无法利用索引的时候,InnoDB会放弃使用行级别锁定而改用表级别的锁定,造成并发性能的降低; (2)当Query使用的索引并不包含所有过滤条件的时候,数据检索使用到的索引键所只想的数据可能有部分并不属于该Query的结果集的行列,但是也会被锁定,因为间隙锁锁定的是一个范围,而不是具体的索引键; (3)当Query在使用索引定位数据的时候,如果使用的索引键一样但访问的数据行不同的时候(索引只是过滤条件的一部分),一样会被锁定。 因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件。 还要特别说明的是,InnoDB除了通过范围条件加锁时使用间隙锁外,如果使用相等条件请求给一个不存在的记录加锁,InnoDB也会使用间隙锁。 4.死锁 MyISAM表锁是deadlock free的,这是因为MyISAM总是一次获得所需的全部锁,要么全部满足,要么等待,因此不会出现死锁。但在InnoDB中,除单个SQL组成的事务外,锁是逐步获得的,当两个事务都需要获得对方持有的排他锁才能继续完成事务,这种循环锁等待就是典型的死锁。 在InnoDB的事务管理和锁定机制中,有专门检测死锁的机制,会在系统中产生死锁之后的很短时间内就检测到该死锁的存在。当InnoDB检测到系统中产生了死锁之后,InnoDB会通过相应的判断来选这产生死锁的两个事务中较小的事务来回滚,而让另外一个较大的事务成功完成。 那InnoDB是以什么来为标准判定事务的大小的呢?MySQL官方手册中也提到了这个问题,实际上在InnoDB发现死锁之后,会计算出两个事务各自插入、更新或者删除的数据量来判定两个事务的大小。也就是说哪个事务所改变的记录条数越多,在死锁中就越不会被回滚掉。 但是有一点需要注意的就是,当产生死锁的场景中涉及到不止InnoDB存储引擎的时候,InnoDB是没办法检测到该死锁的,这时候就只能通过锁定超时限制参数InnoDB_lock_wait_timeout来解决。 需要说明的是,这个参数并不是只用来解决死锁问题,在并发访问比较高的情况下,如果大量事务因无法立即获得所需的锁而挂起,会占用大量计算机资源,造成严重性能问题,甚至拖跨数据库。我们通过设置合适的锁等待超时阈值,可以避免这种情况发生。 通常来说,死锁都是应用设计的问题,通过调整业务流程、数据库对象设计、事务大小,以及访问数据库的SQL语句,绝大部分死锁都可以避免。下面就通过实例来介绍几种避免死锁的常用方法: (1)在应用中,如果不同的程序会并发存取多个表,应尽量约定以相同的顺序来访问表,这样可以大大降低产生死锁的机会。 (2)在程序以批量方式处理数据的时候,如果事先对数据排序,保证每个线程按固定的顺序来处理记录,也可以大大降低出现死锁的可能。 (3)在事务中,如果要更新记录,应该直接申请足够级别的锁,即排他锁,而不应先申请共享锁,更新时再申请排他锁,因为当用户申请排他锁时,其他事务可能又已经获得了相同记录的共享锁,从而造成锁冲突,甚至死锁。 (4)在REPEATABLE-READ隔离级别下,如果两个线程同时对相同条件记录用SELECT...FOR UPDATE加排他锁,在没有符合该条件记录情况下,两个线程都会加锁成功。程序发现记录尚不存在,就试图插入一条新记录,如果两个线程都这么做,就会出现死锁。这种情况下,将隔离级别改成READ COMMITTED,就可避免问题。 (5)当隔离级别为READ COMMITTED时,如果两个线程都先执行SELECT...FOR UPDATE,判断是否存在符合条件的记录,如果没有,就插入记录。此时,只有一个线程能插入成功,另一个线程会出现锁等待,当第1个线程提交后,第2个线程会因主键重出错,但虽然这个线程出错了,却会获得一个排他锁。这时如果有第3个线程又来申请排他锁,也会出现死锁。对于这种情况,可以直接做插入操作,然后再捕获主键重异常,或者在遇到主键重错误时,总是执行ROLLBACK释放获得的排他锁。 5.什么时候使用表锁 对于InnoDB表,在绝大部分情况下都应该使用行级锁,因为事务和行锁往往是我们之所以选择InnoDB表的理由。但在个别特殊事务中,也可以考虑使用表级锁: (1)事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,不仅这个事务执行效率低,而且可能造成其他事务长时间锁等待和锁冲突,这种情况下可以考虑使用表锁来提高该事务的执行速度。 (2)事务涉及多个表,比较复杂,很可能引起死锁,造成大量事务回滚。这种情况也可以考虑一次性锁定事务涉及的表,从而避免死锁、减少数据库因事务回滚带来的开销。 应用中这两种事务不能太多,否则,就应该考虑使用MyISAM表了。 在InnoDB下,使用表锁要注意以下两点。 (1)使用LOCK TABLES虽然可以给InnoDB加表级锁,但必须说明的是,表锁不是由InnoDB存储引擎层管理的,而是由其上一层──MySQL Server负责的,仅当autocommit=0、InnoDB_table_locks=1(默认设置)时,InnoDB层才能知道MySQL加的表锁,MySQL Server也才能感知InnoDB加的行锁,这种情况下,InnoDB才能自动识别涉及表级锁的死锁,否则,InnoDB将无法自动检测并处理这种死锁。 (2)在用 LOCK TABLES对InnoDB表加锁时要注意,要将AUTOCOMMIT设为0,否则MySQL不会给表加锁;事务结束前,不要用UNLOCK TABLES释放表锁,因为UNLOCK TABLES会隐含地提交事务;COMMIT或ROLLBACK并不能释放用LOCK TABLES加的表级锁,必须用UNLOCK TABLES释放表锁。

1006541099824509 2019-12-02 03:14:39 0 浏览量 回答数 0

问题

详解 Spring 3.0 基于 Annotation 的依赖注入实现 配置报错 

kun坤 2020-06-01 09:44:47 3 浏览量 回答数 1

回答

一、系统迁移捅了13亿用户的娄子 故事,是从一桩“离婚再嫁”的案子开始的。 离婚再嫁的主角,是英国银行TSB。 2015年,TSB银行结束了与劳埃德银行(Lloyds Bank)长达20年的“婚姻”,从他们合并的集团中拆分出来,并卖身给了新欢、西班牙公司萨瓦德尔(Sabadell)集团,收购价17亿英镑,按当时的汇率大概是158亿人民币。 然而,过去的20年,世界变了太多,银行业也进步了太多。20年的“婚姻”留给TSB银行的,还有和“前夫”剪不断理还乱的IT系统。 TSB银行540万客户的数十亿记录,都还留在“前夫”劳埃德银行的系统里,而且因为缘分已断,不能白嫖人家的系统,每年还要给前夫交1亿英镑(大约9.3亿人民币)的费用。 这就好像肉身虽然已经和“新欢”在一起,但支付宝和微信账号还是跟“前夫”共用一套,而且还要给“前夫”付账号租金,自然令人不爽。 于是,在筹备了许久之后,2018年,他们终于要行动了:把“前夫”IT系统里的客户信息记录,迁移到“新欢”专门为TSB银行准备的新系统里。 他们把迁移的日子,定在了4月22日星期日的晚上,先把银行的IT系统离线,迁移完之后再上线,恢复客户访问自己银行账户的权限。 为了这场迁移,他们已经投入了超过2500人年的人力成本,西班牙“新欢”集团的CEO在前一年的圣诞节就大声放话:这是全欧洲史无前例的大项目,我们投入了1000多名专业人才,将极大地促进我们在英国的增长。 不过,虽然大佬们在台上豪言壮语,实际上负责迁移的员工们心里却慌得一逼。这个迁移项目本来要筹备18个月,结果时间超了,预算也超了,事情难办的很。 Flag果然不能立太早,打脸的结果很快就来了。 迁移结束,客户的访问权限,他们以为万无一失,但就在20分钟后,收到了问题报告: 有的客户发现自己的钱不见了; 有的客户花了一点小钱,账户里却记录成了花费数千美元; 有的客户登录上去之后,发现不是自己的账户,而是看到了别人的银行账户。 13亿客户的账户记录都出了问题,于是,他们把TSB银行骂成狗,金融监管机构们则连夜找银行喝茶。 而此后的几个星期,银行都在拼命的恢复系统,但数以百万计的客户们已经人心惶惶,拼命的把自己存在TSB银行的钱取出来。 TSB银行,被自己捅的篓子扔进了地狱模式。 而问题的根源,在于测试。 英国金融监管机构金融行为监管局(FCA)首席执行官Andrew Bailey在事故几周后对外公开表示,造成系统混乱的很大原因在于缺少测试,而TSB银行请来救急的IBM专家也发现,TSB银行没有采用严格的上线标准。 而且由于地球上的金融体系都是相连的,事故所造成的错误被永久的保留在了金融体系里,不可逆转。 这起弥天大祸,也让TSB银行赔了很多钱。为了赔偿客户、解决系统出问题后浑水摸鱼的交易、找第三方帮忙总共花了3.302亿英镑,按当时汇率算大约28.4亿人民币。 而TSB的乙方、IT提供商Sabis也因为这起事故收到了1.53亿英镑(超过13亿人民币)的赔偿账单。 而受此影响,TSB银行当年亏损了1.054亿英镑(9.2亿人民币),CEO Paul Pester引咎辞职。 业绩这么差,银行的经营也难以为继,今年11月底TSB关闭了英国86个分行,至少400个工作岗位也因此消失。 二、银行系统很复杂 信息化时代,银行的IT系统也变得越来越复杂。 六十年前,人们只能选择在柜台存取现金,普通客户并没有机会直接接触计算机系统。当时,银行虽然也启用了巨型计算机,但它们只会在一天或一周交易结束的时候对纸质数据进行汇总。 也就是说,银行的IT系统仅由银行员工使用,银行与客户在柜台上的交互用的还是纸质工具。 这种情况在1967年发生了改变。 这一年,世界上第一台自动柜员机(ATM)在英国诞生,并被安装到伦敦北部的巴克莱银行Enfield分行。从此,银行和客户交互的方式发生重大变革。 ITRS Group首席执行官盖伊·沃伦(Guy Warren)解释说: 直到真正的ATM和在线银行业务出现,公众才可以直接访问银行的IT系统。 这还仅仅是个开始。 全球互联的时代,互联网和移动银行的发展进一步拉近了客户和银行IT系统之间的距离,而这样的系统,也越来越成为银行赖以运营的关键所在。 或许你会觉得,登个支付宝/微信,亮出付款码,让小钱钱在银行跟银行之间发生小小的流动,并没有什么难度。但事实上,每一次信息的加载和刷新背后,都发生了复杂的数据移动: 每一次动作可能关联到许多个单独的系统,所有这些系统都必须彼此交互,并与核心大型计算机连通。系统要现在后端复制数据,将现金从一个账户转移到另一个账户,保持同步更新。 而这样的运算量,还要乘以数十亿倍。 根据世界银行的数据,现在,全球至少有69%的成年人都拥有银行账户。人们每一天都在通过银行账户支付账单、贷款还款、订阅各种服务……并且,这些活动常常是跨行,甚至跨国进行的。 一家银行内部的多个IT系统(移动银行、ATM等),不仅需要彼此交互,甚至还必须跟其他国家的银行建立联系。比如我在国内办了一张visa信用卡,在美国也要能消费才行。 三、迁移问题很麻烦 TSB正是栽在了这样的高度复杂性上。 IBM在为TSB编写的报告中指出:新应用程序的组合,对先进微服务的应用和双活数据中心的使用,导致了TSB生产中的复合风险。 如何正确地处理银行IT系统迁移中出现的问题,对于任何一个银行来说,都是不小的挑战。 其中,大量的事前规划和测试工作是不可避免的。 像汇丰银行这样的跨国银行,具有高度复杂、相互关联的系统,这些系统会定期进行测试、迁移和更新。 即使在这方面如此经验丰富,汇丰银行的前IT主管兰开斯特仍坦承:诀窍就是让员工在这件事上付出更多的时间。 他还指出,TSB的IT系统迁移是一件很复杂的事: 我不确定他们是不是真的意识到了这件事的复杂程度。他们甚至没有完全想好要怎么去测试系统。 FCA首席执行官Andrew Bailey则表示: TSB的这一事故反映出他们缺少强大的回归测试。 注:回归测试是软件测试的一种,旨在检验软件原有功能在修改后是否保持完整 而最新的事故报告也引起了hacker news上网友们的热烈讨论。 有网友表示,如果TSB能选择小规模多次迁移,而不是在某一天进行大爆炸式迁移,那这种严重的事故可能就不会发生。 花几周/几个月的时间在生产过程中进行检查,以确保旧数据库和新数据库返回的结构相同。最终,将数据都转移到新数据库中,并在一段时间之后再关闭旧的数据库。这样做效果是比较好的。 而对测试不足导致了银行系统瘫痪的这一调查结论,有人吐槽说: 作为测试工程师,我一点也不意外。花费更多的时间、投入更多的人员来打造更好的测试架构,对于很多公司来说都是“可以节省的成本”。 经理们总是在设定的上线日期前问:“测试咋能花那么多时间?!”真要出事了他们又开始甩锅了。 也有网友严厉批评道:TSB的问题不应该说是测试不足,而是在多个层面上都测试不足,并且缺少可恢复的备份。 也有人指出,避免出错最简单的办法就是减少变化。 问题在于,无论是银行还是其他领域的公司,业务都是在不断进化的。 根据FCA发布的数据,从2017年到2018年,英国金融服务部门报告的技术中断增加了187%。 盖伊·沃伦就认为:系统停机不会消失。问题在于,可接受的度在哪里? 你怎么看呢?在评论区留下你的看法~

有只黑白猫 2020-01-20 11:22:13 0 浏览量 回答数 0

回答

一、软件篇 1、设定虚拟内存 硬盘中有一个很宠大的数据交换文件,它是系统预留给虚拟内存作暂存的地方,很多应用程序都经常会使用到,所以系统需要经常对主存储器作大量的数据存取,因此存取这个档案的速度便构成影响计算机快慢的非常重要因素!一般Windows预设的是由系统自行管理虚拟内存,它会因应不同程序所需而自动调校交换档的大小,但这样的变大缩小会给系统带来额外的负担,令系统运作变慢!有见及此,用户最好自定虚拟内存的最小值和最大值,避免经常变换大小。要设定虚拟内存,在“我的电脑”上按右键选择“属性”,在“高级”选项里的“效能”的对话框中,对“虚拟内存”进行设置。 3、检查应用软件或者驱动程序 有些程序在电脑系统启动会时使系统变慢。如果要是否是这方面的原因,我们可以从“安全模式”启动。因为这是原始启动,“安全模式”运行的要比正常运行时要慢。但是,如果你用“安全模式”启动发现电脑启动速度比正常启动时速度要快,那可能某个程序是导致系统启动速度变慢的原因。 4、桌面图标太多会惹祸 桌面上有太多图标也会降低系统启动速度。Windows每次启动并显示桌面时,都需要逐个查找桌面快捷方式的图标并加载它们,图标越多,所花费的时间当然就越多。同时有些杀毒软件提供了系统启动扫描功能,这将会耗费非常多的时间,其实如果你已经打开了杀毒软件的实时监视功能,那么启动时扫描系统就显得有些多余,还是将这项功能禁止吧! 建议大家将不常用的桌面图标放到一个专门的文件夹中或者干脆删除! 5、ADSL导致的系统启动变慢 默认情况下Windows XP在启动时会对网卡等网络设备进行自检,如果发现网卡的IP地址等未配置好就会对其进行设置,这可能是导致系统启动变慢的真正原因。这时我们可以打开“本地连接”属性菜单,双击“常规”项中的“Internet协议”打开“TCP/IP属性”菜单。将网卡的IP地址配置为一个在公网(默认的网关是192.168.1.1)中尚未使用的数值如192.168.1.X,X取介于2~255之间的值,子网掩码设置为255.255.255.0,默认网关和DNS可取默认设置。 6、字体对速度的影响 虽然 微软 声称Windows操作系统可以安装1000~1500种字体,但实际上当你安装的字体超过500 种时,就会出现问题,比如:字体从应用程序的字体列表中消失以及Windows的启动速度大幅下降。在此建议最好将用不到或者不常用的字体删除,为避免删除后发生意外,可先进行必要的备份。 7、删除随机启动程序 何谓随机启动程序呢?随机启动程序就是在开机时加载的程序。随机启动程序不但拖慢开机时的速度,而且更快地消耗计算机资源以及内存,一般来说,如果想删除随机启动程序,可去“启动”清单中删除,但如果想详细些,例如是QQ、popkiller 之类的软件,是不能在“启动”清单中删除的,要去“附属应用程序”,然后去“系统工具”,再去“系统信息”,进去后,按上方工具列的“工具”,再按“系统组态编辑程序”,进去后,在“启动”的对话框中,就会详细列出在启动电脑时加载的随机启动程序了!XP系统你也可以在“运行”是输入Msconfig调用“系统配置实用程序”才终止系统随机启动程序,2000系统需要从XP中复制msconfig程序。 8、取消背景和关闭activedesktop 不知大家有否留意到,我们平时一直摆放在桌面上漂亮的背景,其实是很浪费计算机资源的!不但如此,而且还拖慢计算机在执行应用程序时的速度!本想美化桌面,但又拖慢计算机的速度,这样我们就需要不在使用背景了,方法是:在桌面上按鼠标右键,再按内容,然后在“背景”的对话框中,选“无”,在“外观”的对话框中,在桌面预设的青绿色,改为黑色......至于关闭activedesktop,即是叫你关闭从桌面上的web画面,例如在桌面上按鼠标右键,再按内容,然后在“背景”的对话框中,有一幅背景,名为Windows XX,那副就是web画面了!所以如何系统配置不高就不要开启。 10、把Windows变得更苗条 与DOS系统相比,Windows过于庞大,而且随着你每天的操作,安装新软件、加载运行库、添加新游戏等等使得它变得更加庞大,而更为重要的是变大的不仅仅是它的目录,还有它的 注册表 和运行库。因为即使删除了某个程序,可是它使用的DLL文件仍然会存在,因而随着使用日久,Windows的启动和退出时需要加载的DLL动态链接库文件越来越大,自然系统运行速度也就越来越慢了。这时我们就需要使用一些彻底删除DLL的程序,它们可以使Windows恢复苗条的身材。建议极品玩家们最好每隔两个月就重新安装一遍Windows,这很有效。 11、更改系统开机时间 虽然你已知道了如何新增和删除一些随机启动程序,但你又知不知道,在开机至到进入Windows的那段时间,计算机在做着什么呢?又或者是,执行着什么程序呢?那些程序,必定要全部载完才开始进入Windows,你有否想过,如果可删除一些不必要的开机时的程序,开机时的速度会否加快呢?答案是会的!想要修改,可按"开始",选"执行",然后键入win.ini,开启后,可以把以下各段落的内容删除,是删内容,千万不要连标题也删除!它们包括:[compatibility]、[compatibility32]、[imecompatibility]、[compatibility95]、[modulecompatibility]和[embedding]。 二、硬件篇 1、Windows系统自行关闭硬盘DMA模式 硬盘的DMA模式大家应该都知道吧,硬盘的PATA模式有DMA33、DMA66、DMA100和DMA133,最新的SATA-150都出来了!一般来说现在大多数人用的还是PATA模式的硬盘,硬盘使用DMA模式相比以前的PIO模式传输的速度要快2~8倍。DMA模式的起用对系统的性能起到了实质的作用。但是你知道吗?Windows 2000、XP、2003系统有时会自行关闭硬盘的DMA模式,自动改用PIO模式运行!这就造成在使用以上系统中硬盘性能突然下降,其中最明显的现象有:系统起动速度明显变慢,一般来说正常Windows XP系统启动时那个由左向右运动的滑条最多走2~4次系统就能启动,但这一问题发生时可能会走5~8次或更多!而且在运行系统时进行硬盘操作时明显感觉变慢,在运行一些大的软件时CPU占用率时常达到100%而产生停顿,玩一些大型3D游戏时画面时有明显停顿,出现以上问题时大家最好看看自己硬盘的DMA模式是不是被Windows 系统自行关闭了。查看自己的系统是否打开DMA模式: a. 双击“管理工具”,然后双击“计算机管理”; b. 单击“系统工具”,然后单击“设备管理器”; c. 展开“IDE ATA/ATAPI 控制器”节点; d. 双击您的“主要IDE控制器”; 2、CPU 和风扇是否正常运转并足够制冷 当CPU风扇转速变慢时,CPU本身的温度就会升高,为了保护CPU的安全,CPU就会自动降低运行频率,从而导致计算机运行速度变慢。有两个方法检测CPU的温度。你可以用“手指测法”用手指试一下处理器的温度是否烫手,但是要注意的是采用这种方法必须先拔掉电源插头,然后接一根接地线来防止身上带的静电击穿CPU以至损坏。另一个比较科学的方法是用带感温器的万用表来检测处理器的温度。 因为处理器的种类和型号不同,合理温度也各不相同。但是总的来说,温度应该低于 110 度。如果你发现处理器的测试高于这处温度,检查一下机箱内的风扇是否正常运转。 3、USB和扫描仪造成的影响 由于Windows 启动时会对各个驱动器(包括光驱)进行检测,因此如果光驱中放置了光盘,也会延长电脑的启动时间。所以如果电脑安装了扫描仪等设备,或在启动时已经连接了USB硬盘,那么不妨试试先将它们断开,看看启动速度是不是有变化。一般来说,由于USB接口速度较慢,因此相应设备会对电脑启动速度有较明显的影响,应该尽量在启动后再连接USB设备。如果没有USB设备,那么建议直接在BIOS设置中将USB功能关闭。 4、是否使用了磁盘压缩 因为“磁盘压缩”可能会使电脑性能急剧下降,造成系统速度的变慢。所以这时你应该检测一下是否使用了“磁盘压缩”,具体操作是在“我的电脑”上点击鼠标右键,从弹出的菜单选择“属性”选项,来检查驱动器的属性。 5、网卡造成的影响 只要设置不当,网卡也会明显影响系统启动速度,你的电脑如果连接在局域网内,安装好网卡驱动程序后,默认情况下系统会自动通过DHCP来获得IP地址,但大多数公司的局域网并没有DHCP服务器,因此如果用户设置成“自动获得IP地址”,系统在启动时就会不断在网络中搜索DHCP 服务器,直到获得IP 地址或超时,自然就影响了启动时间,因此局域网用户最好为自己的电脑指定固定IP地址。 6、文件夹和打印机共享 安装了Windows XP专业版的电脑也会出现启动非常慢的时候,有些时候系统似乎给人死机的感觉,登录系统后,桌面也不出现,电脑就像停止反应,1分钟后才能正常使用。这是由于使用了Bootvis.exe 程序后,其中的Mrxsmb.dll文件为电脑启动添加了67秒的时间! 要解决这个问题,只要停止共享文件夹和打印机即可:选择“开始→设置→网络和拨号连接”,右击“本地连接”,选择“属性”,在打开的窗口中取消“此连接使用下列选定的组件”下的“ Microsoft 网络的文件和打印机共享”前的复选框,重启电脑即可。 7、系统配件配置不当 一些用户在组装机器时往往忽略一些小东西,从而造成计算机整体配件搭配不当,存在着速度上的瓶颈。比如有些朋友选的CPU档次很高,可声卡等却买了普通的便宜货,其实这样做往往是得不偿失。因为这样一来计算机在运行游戏、播放影碟时由于声卡占用CPU资源较高且其数据传输速度较慢,或者其根本无硬件解码而需要采用软件解码方式,常常会引起声音的停顿,甚至导致程序的运行断断续续。又如有些朋友的机器是升了级的,过去老机器上的一些部件如内存条舍不得抛弃,装在新机器上照用,可是由于老内存的速度限制,往往使新机器必须降低速度来迁就它,从而降低了整机的性能,极大地影响了整体的运行速度。 9、断开不用的网络驱动器 为了消除或减少 Windows 必须重新建立的网络连接数目,建议将一些不需要使用的网络驱动器断开,也就是进入“我的电脑”,右击已经建立映射的网络驱动器,选择“断开”即可。 10、缺少足够的内存 Windows操作系统所带来的优点之一就是多线性、多任务,系统可以利用CPU来进行分时操作,以便你同时做许多事情。但事情有利自然有弊,多任务操作也会对你的机器提出更高的要求。朋友们都知道即使是一个最常用的WORD软件也要求最好有16MB左右的内存,而运行如3D MAX等大型软件时,64MB的内存也不够用。所以此时系统就会自动采用硬盘空间来虚拟主内存,用于运行程序和储存交换文件以及各种临时文件。由于硬盘是机械结构,而内存是电子结构,它们两者之间的速度相差好几个数量级,因而使用硬盘来虚拟主内存将导致程序运行的速度大幅度降低。 11、硬盘空间不足 使用Windows系统平台的缺点之一就是对文件的管理不清楚,你有时根本就不知道这个文件对系统是否有用,因而Windows目录下的文件数目越来越多,容量也越来越庞大,加之现在的软件都喜欢越做越大,再加上一些系统产生的临时文件、交换文件,所有这些都会使得硬盘可用空间变小。当硬盘的可用空间小到一定程度时,就会造成系统的交换文件、临时文件缺乏可用空间,降低了系统的运行效率。更为重要的是由于我们平时频繁在硬盘上储存、删除各种软件,使得硬盘的可用空间变得支离破碎,因此系统在存储文件时常常没有按连续的顺序存放,这将导致系统存储和读取文件时频繁移动磁头,极大地降低了系统的运行速度。 12、硬盘分区太多也有错 如果你的Windows 2000没有升级到SP3或SP4,并且定义了太多的分区,那么也会使启动变得很漫长,甚至挂起。所以建议升级最新的SP4,同时最好不要为硬盘分太多的区。因为Windows 在启动时必须装载每个分区,随着分区数量的增多,完成此操作的时间总量也会不断增长。 三、病毒篇 如果你的计算机感染了病毒,那么系统的运行速度会大幅度变慢。病毒入侵后,首先占领内存这个据点,然后便以此为根据地在内存中开始漫无休止地复制自己,随着它越来越庞大,很快就占用了系统大量的内存,导致正常程序运行时因缺少主内存而变慢,甚至不能启动;同时病毒程序会迫使CPU转而执行无用的垃圾程序,使得系统始终处于忙碌状态,从而影响了正常程序的运行,导致计算机速度变慢。下面我们就介绍几种能使系统变慢的病毒。 1、使系统变慢的bride病毒 病毒类型:黑客程序 发作时间:随机 传播方式:网络 感染对象:网络 警惕程度:★★★★ 病毒介绍: 此病毒可以在Windows 2000、Windows XP等操作系统环境下正常运行。运行时会自动连接 www.hotmail.com网站,如果无法连接到此网站,则病毒会休眠几分钟,然后修改注册表将自己加入注册表自启动项,病毒会释放出四个病毒体和一个有漏洞的病毒邮件并通过邮件系统向外乱发邮件,病毒还会释放出FUNLOVE病毒感染局域网计算机,最后病毒还会杀掉已知的几十家反病毒软件,使这些反病毒软件失效。 病毒特征 如果用户发现计算机中有这些特征,则很有可能中了此病毒。 ·病毒运行后会自动连接 www.hotmail.com网站。 ·病毒会释放出Bride.exe,Msconfig.exe,Regedit.exe三个文件到系统目录;释放出:Help.eml, Explorer.exe文件到桌面。 ·病毒会在注册表的HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun项中加入病毒Regedit.exe的路径。 ·病毒运行时会释放出一个FUNLOVE病毒并将之执行,而FUNLOVE病毒会在计算机中大量繁殖,造成系统变慢,网络阻塞。 ·病毒会寻找计算机中的邮件地址,然后按照地址向外大量发送标题为:<被感染的计算机机名>(例:如果用户的计算机名为:张冬, 则病毒邮件的标题为:张冬)的病毒邮件。 ·病毒还会杀掉几十家国外著名的反病毒软件。 用户如果在自己的计算机中发现以上全部或部分现象,则很有可能中了Bride(Worm.bride)病毒,请用户立刻用手中的杀毒软件进行清除。 2、使系统变慢的阿芙伦病毒 病毒类型:蠕虫病毒 发作时间:随机 传播方式:网络/文件 感染对象:网络 警惕程度:★★★★ 病毒介绍: 此病毒可以在Windows 9X、Windows NT、Windows 2000、Windows XP等操作系统环境下正常运行。病毒运行时将自己复到到TEMP、SYSTEM、RECYCLED目录下,并随机生成文件名。该病毒运行后,会使消耗大量的系统资源,使系统明显变慢,并且杀掉一些正在运行的反病毒软件,建立四个线程在局域网中疯狂传播。 病毒特征 如果用户发现计算机中有这些特征,则很有可能中了此病毒: ·病毒运行时会将自己复到到TEMP、SYSTEM、RECYCLED目录下,文件名随机 ·病毒运行时会使系统明显变慢 ·病毒会杀掉一些正在运行的反病毒软件 ·病毒会修改注册表的自启动项进行自启动 ·病毒会建立四个线程在局域网中传播 用户如果在自己的计算机中发现以上全部或部分现象,则很有可能中了“阿芙伦(Worm.Avron)”病毒,由于此病毒没有固定的病毒文件名,所以,最好还是选用杀毒软件进行清除。 3、恶性蠕虫 震荡波 病毒名称: Worm.Sasser 中文名称: 震荡波 病毒别名: W32/Sasser.worm [Mcafee] 病毒类型: 蠕虫 受影响系统:WinNT/Win2000/WinXP/Win2003 病毒感染症状: ·莫名其妙地死机或重新启动计算机; ·系统速度极慢,cpu占用100%; ·网络变慢; ·最重要的是,任务管理器里有一个叫"avserve.exe"的进程在运行! 破坏方式: ·利用WINDOWS平台的 Lsass 漏洞进行广泛传播,开启上百个线程不停攻击其它网上其它系统,堵塞网络。病毒的攻击行为可让系统不停的倒计时重启。 ·和最近出现的大部分蠕虫病毒不同,该病毒并不通过邮件传播,而是通过命令易受感染的机器 下载特定文件并运行,来达到感染的目的。 ·文件名为:avserve.exe 解决方案: ·请升级您的操作系统,免受攻击 ·请打开个人防火墙屏蔽端口:445、5554和9996,防止名为avserve.exe的程序访问网络 ·手工解决方案: 首先,若系统为WinMe/WinXP,则请先关闭系统还原功能; 步骤一,使用进程程序管理器结束病毒进程 右键单击任务栏,弹出菜单,选择“任务管理器”,调出“Windows任务管理器”窗口。在任务管理器中,单击“进程”标签,在例表栏内找到病毒进程“avserve.exe”,单击“结束进程按钮”,点击“是”,结束病毒进程,然后关闭“Windows任务管理器”; 步骤二,查找并删除病毒程序 通过“我的电脑”或“资源管理器”进入 系统安装目录(Winnt或windows),找到文件“avser ve.exe”,将它删除;然后进入系统目录(Winntsystem32或windowssystem32),找 到文件"*_up.exe", 将它们删除; 步骤三,清除病毒在注册表里添加的项 打开注册表编辑器: 点击开始——>运行, 输入REGEDIT, 按Enter; 在左边的面板中, 双击(按箭头顺序查找,找到后双击): HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRun 在右边的面板中, 找到并删除如下项目:"avserve.exe" = %SystemRoot%avserve.exe 关闭注册表编辑器。 第二部份 系统加速 一、Windows 98 1、不要加载太多随机启动程序 不要在开机时载入太多不必要的随机启动程序。选择“开始→程序→附件→系统工具→系统信息→系统信息对话框”,然后,选择“工具→系统配置实用程序→启动”,只需要internat.exe前打上钩,其他项都可以不需要,选中后确定重起即可。 2、转换系统文件格式 将硬盘由FAT16转为FAT32。 3、不要轻易使用背景 不要使用ActiveDesktop,否则系统运行速度会因此减慢(右击屏幕→寻显示器属性→Web标签→将其中关于“活动桌面”和“频道”的选项全部取消)。 4、设置虚拟内存 自己设定虚拟内存为机器内存的3倍,例如:有32M的内存就设虚拟内存为96M,且最大值和最小值都一样(此设定可通过“控制面板→系统→性能→虚拟内存”来设置)。 5、一些优化设置 a、到控制面板中,选择“系统→性能→ 文件系统”。将硬盘标签的“计算机主要用途”改为网络服务器,“预读式优化"调到全速。 b、将“软盘”标签中“每次启动就搜寻新的软驱”取消。 c、CD-ROM中的“追加高速缓存”调至最大,访问方式选四倍速或更快的CD-ROM。 6、定期对系统进行整理 定期使用下列工具:磁盘扫描、磁盘清理、碎片整理、系统文件检查器(ASD)、Dr?Watson等。 二、Windows 2000 1、升级文件系统 a、如果你所用的操作系统是win 9x与win 2000双重启动的话,建议文件系统格式都用FAT32格式,这样一来可以节省硬盘空间,二来也可以9x与2000之间能实行资源共享。 提醒:要实现这样的双重启动,最好是先在纯DOS环境下安装完9x在C区,再在9x中或者用win 2000启动盘启动在DOS环境下安装2000在另一个区内,并且此区起码要有800M的空间以上 b、如果阁下只使用win 2000的话,建议将文件系统格式转化为NTFS格式,这样一来可节省硬盘空间,二来稳定性和运转速度更高,并且此文件系统格式有很好的纠错性;但这样一来,DOS和win 9x系统就不能在这文件系统格式中运行,这也是上面所说做双启动最好要用FAT32格式才能保证资源共享的原因。而且,某些应用程序也不能在此文件系统格式中运行,大多是DOS下的游戏类。 提醒:在win 2000下将文件系统升级为NTFS格式的方法是,点击“开始-程序-附件”选中“命令提示符”,然后在打开的提示符窗口输入"convert drive_letter:/fs:ntfs",其中的"drive"是你所要升级的硬盘分区符号,如C区;还需要说明的是,升级文件系统,不会破坏所升级硬盘分区里的文件,无需要备份。 · 再运行“添加-删除程序”,就会看见多出了个“添加/删除 Windows 组件”的选项; b、打开“文件夹选项”,在“查看”标签里选中“显示所有文件和文件夹”,此时在你安装win 2000下的区盘根目录下会出现Autoexec.bat和Config.sys两个文件,事实上这两个文件里面根本没有任何内容,可以将它们安全删除。 c、右击“我的电脑”,选中“管理”,在点“服务和应用程序”下的“服务”选项,会看见win 2000上加载的各个程序组见,其中有许多是关于局域网设置或其它一些功能的,你完全可以将你不使用的程序禁用; 如:Alertr,如果你不是处于局域网中,完全可以它设置为禁用;还有Fax Service,不发传真的设置成禁用;Print Spooler,没有打印机的设置成制用;Uninterruptible power Supply,没有UPS的也设置成禁用,这些加载程序你自己可以根据自己实际情况进行设置。 各个加载程序后面都有说明,以及运行状态;选中了要禁用的程序,右击它,选“属性”,然后单击停止,并将“启动类型”设置为“手动”或者“已禁用”就行了 d、关掉调试器Dr. Watson; 运行drwtsn32,把除了“转储全部线程上下文”之外的全都去掉。否则一旦有程序出错,硬盘会响很久,而且会占用很多空间。如果你以前遇到过这种情况,请查找user.dmp文件并删掉,可能会省掉几十兆的空间。这是出错程序的现场,对我们没用。另外蓝屏时出现的memory.dmp也可删掉。可在我的电脑/属性中关掉 “答案来源于网络,供您参考” 希望以上信息可以帮到您!

牧明 2019-12-02 02:15:52 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板