志在指尖
用双手敲打未来

在每一次的面试中总结、成长

志在指尖创始人-谭科阅读(2688)

假如你想历练下本人,不晓得本人哪方面需求进步。那么,去找几家公司面试吧。这样会帮你更好的生长,面试完你会晓得本人的差距。每一次面试都能发现本人的欠缺陷,学问盲区,快速找到需求进步的学问点,以及需求进步的其他方面的综合才能。
很多同窗说,我面试了几十家公司都没有胜利。听到这话,根本上这个同窗我不会去录用。
比拟有意义的是,面试时,经常能遇到一些招聘者,问啥啥不晓得,随意问几个问题,就懵了。
常见的比拟考验综合才能的几个面试问题:
1.一分钟时间,论述本人的整体优势
2.你平常的学习渠道有哪些
3.论述你工作中主要担任的内容
4.从开发代码提交,整个后续流程是怎样的?
5.遇到问题的处理思绪是哪些
6.你以为本人需求本人的是哪些?
7.假如让你评价这次面试,你给本人打几分?
OK,如上每个问题,面试官都是有很强的目的性的。
充沛考证的你的综合才能。
当然,面试不同的岗位,问题不尽相同,假如是管理岗,还会有一些其他更考验综合才能的问题。
总之一点:
每一次面试完,你能否面试完毕后,都能把这些问题想分明?下次面试,能答复好?
针对当前阶段的确欠缺的才能,能否布置时间、精神去进步?
这样才会生长。
否则,这次面试,只是糜费了时间和时机。
每面试一次,就糜费一次时机。

winform播放wav文件代码分享

志在指尖创始人-谭科阅读(2666)

usingSystem.Reflection;
usingSystem.IO;
usingSystem.Resources;
usingSystem.Media;
usingSystem.Diagnostics;
namespaceCN.OutOfMemory.Csharp
{
publicpartialclassForm1:Form
{
publicForm1()
{
InitializeComponent();
}
privatevoidForm1_Load(objectsender,EventArgse)
{
Assemblyassembly;
StreamsoundStream;
SoundPlayersp;
assembly=Assembly.GetExecutingAssembly();
sp=newSoundPlayer(assembly.GetManifestResourceStream(“Yournamespace.Dreamer.wav”));//wav文件路径
sp.Play();
}
}
}
/*SoundPlayersp=newSoundPlayer(global::WindowsApplication1.Properties.Resources.yoursoundfilename);*/

怎么增强自己的学习才能?

志在指尖创始人-谭科阅读(2518)

首先,咱们来区分两种学习。一类叫“以常识为中心的学习”,一类叫“以自我为中心的学习”。
“以常识为中心”的学习也叫学院式学习,是以通过考试或许科学研究为意图,首要着重对常识的了解、记忆、概括、解题。“以自我为中心的学习”也叫成人学习,首要着重处理自己的问题、进步自己的才能。
咱们要处理的首要矛盾是“怎样进步学习才能”,归于第二种学习的范畴。
“以自我为中心的学习”首要包含三个维度:
要想进步学习才能,就要从进步内化和运用常识的才能、剖析和收拾信息的才能、诘问和反思阅历的才能这三个维度入手,而且学会建立自己的常识体系,到达知行合一。
当你把握了这种办法时,无论是学习专业常识的才能,仍是学习某种技术、用于处理生活中的详细问题的才能都会得到相应的进步。
这篇文章分别从“以自我为中心的学习”学习的三个维度进行了阐释,给出了详细可执行的举动计划。
1
内化和运用常识
《这样读书就够了》一书中,作者给出了一种在读书的进程中,通过3张便签来协助完成“内化与运用常识”的办法:
前几天收到一个小朋友的私信,满满的都是冤枉:“小姐姐我听了你的主张去读了《学习之道》,可是我觉得并没有什么特别的呀。里边讲的道理我早就知道了,但我仍是学习欠好。”
“XXX我早就知道了”这句话是不是听起来很耳熟?
人们在接触到新的信息时,总是会情不自禁地用现已知道的内容去匹配它,用“已知”去附会“新知”,所以就以为自己看透了、读懂了。
这种思想方式并不是与生俱来的,事实上它来源于在校园中学习时教师教给咱们的习气:总是概括阶段粗心、文章中心思想,用过去学过的办法来处理新的问题。
这种思想方式自身没有错,比方通过联络新课程与旧课程,融会贯通,构建常识网络,用现已把握的公式推导,得到教材给出的新公式能够加深了解、协助记忆。这个推导的进程,自身便是从旧知指向新知的箭头。
附会自身不是问题,最大的问题是止步于附会。找到新知与旧知的相同之处很容易,人人都能做到;而找到不同之处,则需要你去思考。
好的学习者则会诘问,这个信息和我曾经知道的内容细节的不同在哪儿?适用条件有没有不同?对细微的常识有多敏锐,就表现了你的学习才能有多强。
市面上常见的进步人际联系与执行力的畅销书,比方卡耐基《人性的弱点》,比方柯维《高效能人士的七个习气》,有人说前者是“进步人际联系的圣经”,也有人说它“讲的是谁都懂的道理,可是犯错的人底子意识不到,所以底子没用”;有人说后者“改变了自己的人生轨迹”,也有人说它“陈词滥调,名不副实”。
为什么会有截然相反的两种评论呢?除掉个人了解才能不同的要素,第二种人显然更多地附会旧知。
提出新的理论的人少之又少,但同类的书中它们之所以能成为佼佼者,很重要的一个原因是它们把“陈词滥调”进行了“生动演绎”——你本来就听说过的道理,一向不知道怎样实践,它告知你怎样把这些道理用在生活中。这是一种十分了不起的才能,值得咱们去花钱花时刻在这本书上。
具有内化和运用常识的一个表现,便是把附会的天性反应,晋级为界定新知旧知二者鸿沟的理性反应,然后能更深化、更敏锐、更明晰地了解新知,同时还加深了对旧知的知道。
咱们回看上面的“便签法”。在“重述信息”(I便签)这个进程中,许多人会止步于附会旧知,或许干脆就直接摘录了原文中的内容。就算你把书里的这一段背下来了,它也不是你自己的。
“重述”的含义在于“了解”,假如不能充分了解文中的内容,是很难用自己的话表达的。为了到达“内化与运用”的意图,能够在详细操作时将原文常识总结或加工出明确详细的操作办法或主张进程。
在“回想阅历”(A1便签)这个进程中,切忌泛泛而谈。没有详细时刻、详细事件的都是泛泛而谈,讲的是认知而非详细阅历。
让这个进程执行性更强,能够参考这些要素:
记载的事件有必要是自己亲身阅历的,亲眼所见,亲耳所闻;
叙事表现了原因、通过、成果;
原文或I便签的许多要素有明确的对应。
A1便签最要害的是经由新的常识点刺激,咱们能够更好地了解、反思自己的阅历,然后把自己的常识和阅历结合起来,以取得个人成长。
当你要规划A2时,先问自己:“这件事对我来说有多重要?”假如在原书中很重要,可是对我自己不重要,无妨到此为止,去看后边的内容吧。
当你真的决议要把书中的常识用在实际当中时,先定方针。规划举动有必要是自己能够完成的举动,而不是对原文的摘录,哪怕原书的主张给的十分详细,也不能算成自己的常识。
咱们总是习气于在新年到来之际“表决计”:“新的一年,我要读100本书,我要瘦20斤,我要……”;总是喜爱在考试完毕后发誓“下个学期我不能再这样颓废了,我要好好学习”,一般信誓旦旦立下的方针过了三分钟热度就再也没碰过。
由于这些方针都太远大了,大到你自己都不知道该怎样努力才能完成它。当你计划执行“规划运用”(A2便签)进程时,要遵循方针SMART准则:
先给自己定一个详细的(Specific)、可衡量的(Measurable)、能够到达的(Attainable)、与其他方针具有必定的相关性的(Relevant)、具有明确的截止期限的(Time-bound)方针。
然后问问自己:详细举动进程是什么?谁?在哪里?何时开始?是否在运用了原文信息或I便签的办法?都是自己能做到的或推动别人做到的吗?能丈量做到的程度吗?
只有对“规划运用”这个进程的那些问题很明晰,才能进步对决计或慨叹的辨识力。能够判别哪些决计众多的话看起来很漂亮,可是无法落地;哪些是确实可行脚踏实地的主张——这是一项很重要的学习才能。
2
剖析和收拾信息
剖析和收拾信息的才能是学习才能的重要组成部分。在一个信息远多过常识的年代,人们每天都要接触大量的信息流。
假如你不具有这种才能,或许今天看到“人际联系欠好,是由于你不知道这几点”所以觉得人际联系最重要,明日发现“不懂得时刻办理,你现已输在了起点”,后天又发现“情商才是你最大的短板”。
有一些自媒体人和写手为了获取阅览量会刻意地偏激、夸张、煽情乃至误导。
并非一切信息都是常识。二者最首要的不同在于常识的上下文首要显明来龙去脉和适用鸿沟。怎样防止盲从轻信,鉴别那些信息是对自己有利的呢?能够试着从以下8个方面入手:
剖析信息的要害是诘问来龙去脉:
前(前车之鉴):为什么这件事对我重要?他是怎样引出这个信息的?
因(相因相生):作者提出了哪些关于原因的假定?是怎样验证或扫除这些假定的?还有其他可行性吗?
后(以观后效):若依从信息去做之后会怎样?对我的优点(功效)是什么?
果(自作自受):不这么做的成果是什么?不改变的问题有多严峻?
收拾信息的要害是适用鸿沟:
适(拔苗助长):有没有相反的观念?有没有不支撑这个的案例?
用(运用条件):要这样做,得详细哪些条件(考虑本钱收益,考虑态度才能……)什么情况下是不管用的?
边(拐弯抹角):早年有没有相似的(或乍看起来差不多的)信息?其他范畴/行业/作者怎样看待相似问题?
界(楚河汉界):无论是相反的仍是相似的信息,和这个信息的真实差异是什么?接壤在哪里?
下面我以在知乎引起热议的《咪蒙:我为什么支撑实习生休学?》为例,来试着用上面的8个方面剖析与收拾这篇文章的内容。(灰色字是例子,不想看能够直接跳读到下一个部分)
先考虑来龙去脉:
——为什么这件事对我重要?
——嗯我正在读大学,而咪蒙却支撑休学,和我是有联系的。
留意,这个地方假如断定的是“对我不重要”,能够直接关掉这篇文章了。假如以为不重要还持续看,接下来的每一分钟时刻除了变成沉没本钱以外,对你不会有任何优点。
——作者是怎样引出这个信息的?
——她的实习生学了不喜爱的专业,为了自己的“喜爱”休学了,作者支撑而咪蒙以为“为了学习,你休学吧。”
——作者提出了哪些关于原因的假定?
——作者以为:①现在大学的许多课,太没营养了,浪费时刻,也浪费生命。②人生最难的便是找到自己喜爱的,假如你找到了,就去做,不必管什么狗屁的尘俗规范。③互联网年代,那些野生的人才,往往才是最有爆发力的。
——是怎样验证或扫除这些假定的?
——关于假定1她举了一些个例来印证她的观念。
请留意这儿,她的样本是为了支撑自己的观念提出的,并没有说到人群中有多少教师是“是极不走心的”,只是含糊地说“许多教师”,没有任何来自权威机构的数据的支撑。而在我的认知里,四年间我上过的几十门课程中,如她所说的不足3人。
关于假定2,作者没有论证。什么是自己喜爱的?怎样断定自己是不是真的喜爱?有规范能够参照吗?怎样样才算“找到了?”这是一个没有根据的观念。
关于假定3,有知友指出论据里“北大教授”说的话其实是哈佛一名教育学家说的,而且这名教育家十分重视基础教育。作者的论据与观念矛盾。
——还有其他可行性吗?
——我或许在结业之后能找到自己“喜爱的事业”,既拿到了文凭也完成了愿望;也或许在大学期间一边读书,一边“完成愿望”;也或许一辈子都找不到自己的“喜爱”;也或许休学了,“喜爱”的事业失利了,一辈子也没有成为“成功人士”;也或许从明日起奋发图强成了一个学霸。
——若依从信息去做之后会怎样?对我的优点(功效)是什么?
——依从作者的观念,我应该休学。或许的好的成果是我靠着在社会中锻炼走向了人生巅峰,坏的成果是我或许拿不到学位证还一事无成。
——不这么做的成果是什么?不改变的问题有多严峻?
——我或许维持现状,欠好不坏地过完四年。不改变如同也没什么严峻的。
再考虑适用鸿沟:
——有没有相反的观念?有没有不支撑这个观念的案例?
——有。作者自己便是个不支撑她观念的案例,作者是山东大学的文学硕士,让自己的孩子上最好的校园,却支撑实习生休学。
——要这样做,得详细哪些条件(考虑本钱收益,考虑态度才能……)?什么情况下是不管用的?
——作者没有给出任何详细的条件,假如我要去做这件事的话,首先要考虑休学本钱。
假如“喜爱的事”失利的话或许得从头高考,这个本钱有点高。靠写字挣钱养活自己,万一我灵感干涸了怎样办?假如读者不喜爱我写的东西怎样办?假如我挣的钱不行花怎样办?我想去的传媒公司榜首门槛是学历怎样办?这些都是我要考虑的要素。
——早年有没有相似的(或乍看起来差不多的)信息?其他范畴/行业/作者怎样看待相似问题?
——有,“读书无用论”。其间的两种:一种是高学历的人给学历没那么高的人打工;另一种是读了许多书最后都忘了。
观念一偏重的是“单一原因”导致“仅有成果”,事实上构成这一成果的原因是复杂的;观念二没有考虑到“成果是多样的”,即“不读书的话,社会地位、经济收入”或许都会有所不同,而只看到了“忘记了”这一方面。
——无论是相反的仍是相似的信息,和这个信息的真实差异是什么?接壤在哪里?
——视点不同。这篇文章的偏重于“理想”,上面的两个偏重于“原因和成果”。相反的信息如知乎问题“怎样看待《咪蒙:我为什么支撑实习生休学》”下前几位答主,偏重于品德、营销战略、经济水相等不同方面。
重要的不是信息是从哪里来的,重要的是无论拿到什么信息,咱们能够去判别、加工信息的质量,能够给他补上上下文。你越能言必有中地问到这8个问题,就越能表现自己的学习才能。
想要进步学习才能,就要在一切与学习有关的工作上反求诸己。
这儿的“学习”是广义的学习,既包含“以常识为中心”也包含“以自我为中心”。许多时分咱们总是习气于以为“都是别人的原因”:
从小没有养成好的学习习气是由于自己的父母不上心;
成绩欠好是由于教师水平不行讲得欠好;
和女朋友联系欠好老吵架是由于她太作;
和男朋友联系欠好老暗斗是由于他不行爱自己;
和上司发生争执是由于他太反常……
也许你说的这些理由都对,可是,学习仍是欠好;仍是没有良好的亲密联系;工作人际联系也一塌糊涂。
而“反求诸己”的意思则是,从自己开始改变——就算不是自己的原因,但它对我很重要,我也应该做点什么来让它变得更好不是吗?
为什么大家在校的时分看起来都差不多,可是脱离校园几年之后就天差地别了呢?其实每一个人的特质和才能本来就不同很大,只不过在校园的时分你只看到了学习成绩,就误以为现已了解了他的全部:
结业1年之后,交流才能和在过错中学习的才能带来的影响就会闪现;
结业3年之后,处理问题的才能、心情才能、联系才能就会把距离拉大;
结业5年之后,拼的是自我办理才能,逻辑才能和影响力;
结业10年之后拼的是成就、幸福,而这些首要来自于在婚姻中不断成长的才能,教育子女的才能,办理和激励别人的才能。
常识不能改变命运,但才能改变命运。对资产不多的年轻人来说,最优的出资要出资到自己的才能上。在一切具有的可控性要素中,只有才能的增长能带来指数增长的自我增值。
而学习才能是一切才能的元才能。
3
诘问和反思阅历
苏格拉底说,未经反思的人生不值得过。
并不是一切的阅历都是阅历,并不是一切的阅历都是才智。假如不加以明觉精察,不进行反思、总结,那阅历就不或许变成才智。
大卫?库伯(Davidkolb)以为,阅历学习进程是由四个适应性学习阶段构成的环形结构,包含详细阅历,反思性调查,笼统概念化,主动实践。
详细阅历是让学习者彻底投入一种新的体会;
反思性调查是学习者在停下的时分对现已历的体会加以思考;
笼统概念化是学习者有必要到达能了解所调查的内容的程度而且吸收它们使之成为合乎逻辑的概念;
到了主动实践阶段,学习者要验证这些概念并将它们运用到制定战略、处理问题之中去。
在“内化和运用常识部分”咱们介绍了便签法,再来复习一下这部分内容吧:
改善一下,就得到了“诘问与反思”,完成库伯学习圈:
在真实的举动中检核信息,然后发现新问题再去反思,如此构成循环。
诘问和反思阅历,在阅历中学习的要点如下:
A1部分用来描绘自己的相关阅历。必定要是自己亲身遇到的问题,不能是幻想的问题、理论的问题,或许未来或许发生的问题。问题最好是急迫的、比较重要的,由于处理无关痛痒的问题很难带来真实的学习。要尽或许简短。没必要进行过多剖析,用几句话简要描绘就能够了。
I部分用来重述信息,澄清问题,了解问题,找到根源,然后从头界说问题。当在A1便签中写下问题时,必定不要急于寻觅答案或许采取举动。必定不要直接从A1跳到A2。由于同样是自己的阅历,在读书时想到的和在处理问题时写下的A1有着本质的差异。未经反思的阅历都是不可靠的,未经诘问的问题不是真实的问题。
经反思,背后的假定、条件或规范往往是含糊、片面或彻底过错的。
与第二部分“剖析和收拾信息”相似,对自己提出的问题诘问的来龙去脉:
前(前车之鉴):为什么这件事对我重要?是怎样呈现这个问题的?
因(相因相生):都有哪些关于原因的假定?怎样验证或扫除这些假定的?还有其别人能帮我思考,给出更多挑选或或许性吗?
后(以观后效):若这个问题处理了,最好的成果是什么样?那是我期待的吗?
果(自作自受):假如我什么都不做,会发生什么?
然后对问题的原因假定诘问适用鸿沟:
适(拔苗助长):有没有人会不同意我对原因的假定?有没有不符合这个假定的实例?
用(运用条件):要处理这个问题,需要具有哪些条件(考虑本钱收益,考虑态度才能……)?这件事能够用什么其他方式来完成?
边(拐弯抹角):有没有可供借鉴的情况?其他范畴/行业/人怎样处理相似问题?
界(楚河汉界):无论是不同的意见仍是相似的问题,和我的思路的真实差异是什么?接壤在哪里?
在写A2的时分,要留意方针性、举动性、关联性、可控性。
仍然优先考虑方针,问题处理到什么程度、到达什么效果你就满意了。这样的话,你在A2中写下的举动或许运用,都是为了拉近现状跟方针状态之间的距离。
别的,尽或许要求自己在A2便签写下一个以上的举动计划。由于有多个备选的计划会大大增加找到更好的成果的或许性。到了最后在归纳考量每个计划的现实性、可执行性、本钱和收益,根据可控性的要求锁定详细举动。
你会惊讶地发现,你一般以为需要处理的、最近一向很困扰自己的问题,通过反思、诘问,大部分都会被从头界说。
在阅历中学习,最难的是诘问的不同视角。
阅历经由反思和诘问能够沉淀成信息,信息通过剖析和收拾能够升华为常识,常识通过联合和举动会内化为才能,举动带来新的阅历,阅览带来新的信息,反思带来新的常识。如此不断在体会和反思中循环,就到达了知行合一,产生了学习之道。

关于Spring 的面试题

志在指尖创始人-谭科阅读(2573)

Spring 面试题(基础篇)

1.什么是 spring?
2.使用 Spring 框架的好处是什么?
3.Spring 由哪些模块组成?
4.核心容器(应用上下文) 模块。
5.BeanFactory – BeanFactory 实现举例。
6.XMLBeanFactory
7.解释 AOP 模块
8.解释 JDBC 抽象和 DAO 模块。
9.解释对象/关系映射集成模块。
10.解释 WEB 模块。
11.Spring 配置文件
12.什么是 Spring IOC 容器?
13.IOC 的优点是什么?
14.ApplicationContext 通常的实现是什么?
15.Bean 工厂和 Application contexts 有什么区别?
16.一个 Spring 的应用看起来象什么?
17.什么是 Spring 的依赖注入?
18.有哪些不同类型的 IOC(依赖注入)方式?
19.哪种依赖注入方式你建议使用,构造器注入,还是 Setter 方法注入?
20.什么是 Spring beans?
21.一个 Spring Bean 定义 包含什么?
22.你怎样定义类的作用域?
23.解释 Spring 支持的几种 bean 的作用域。
24.Spring 框架中的单例 bean 是线程安全的吗?
25.解释 Spring 框架中 bean 的生命周期。
26.哪些是重要的 bean 生命周期方法?
27.什么是 Spring 的内部 bean?
28.在 Spring 中如何注入一个 java 集合?
29.什么是 bean 装配?
30.什么是 bean 的自动装配?
31.解释不同方式的自动装配 。
32.自动装配有哪些局限性 ?
33.你可以在 Spring 中注入一个 null 和一个空字符串吗?
34.什么是基于 Java 的 Spring 注解配置?
35.什么是基于注解的容器配置?
36.怎样开启注解装配?
37.@Required 注解
38.@Autowired 注解
39.@Qualifier 注解
40.在 Spring 框架中如何更有效地使用 JDBC?
41.JdbcTemplate
42.Spring 对 DAO 的支持
43.使用 Spring 通过什么方式访问 Hibernate?
44.Spring 支持的 ORM
45.如何通过 HibernateDaoSupport 将 Spring 和 Hibernate 结合起来?
46.Spring 支持的事务管理类型
47.Spring 框架的事务管理有哪些优点?
48.你更倾向用那种事务管理类型?
49.解释 AOP
50.Aspect 切面
51.在 Spring AOP 中,关注点和横切关注的区别是什 么?
52.连接点
53.通知
54.切点
55.什么是引入?
56.什么是目标对象?
57.什么是代理?
58.有几种不同类型的自动代理?
59.什么是织入。什么是织入应用的不同点?
60.解释基于 XML Schema 方式的切面实现。
61.解释基于注解的切面实现
62.什么是 Spring 的 MVC 框架?
63.DispatcherServlet
64.WebApplicationContext
65.什么是 Spring MVC 框架的控制器?
66.@Controller 注解
67.@RequestMapping 注解

改进程序员日子质量的习惯

志在指尖创始人-谭科阅读(2362)

规则的日子
不多说很多网上段子什么的,说一个程序员最容易得的:腰肌劳损、腰椎盘杰出、颈椎弯曲之类的病痛。都听了不少,危害其实真的很严重。久远方案,你花了很多时刻成为一个大牛,然后得了各种毛病,又难治,手尾长。你的糟蹋的时刻和金钱,都是不可估计的,如果你仍是一个一般人,不是大牛,何来时刻和金钱去看病?编程的作业是需求精力的,一个好的日子习气,让自己的身体处于高效作业状态下。你发挥的价值比那些不规则的人好多了。
饮食方面
先来看看一些极为不健康的饿法:
1.早上太晚,没时刻吃早餐,匆匆忙忙赶到办公室饿着肚子干到正午。
2.正午外面太阳太热了,外卖已吃腻,两杯咖啡打发下午。
3.晚上好饿呀,撑不住了,正道人间甘旨,何不享用今宵。
再来看看健康的饿法:
1、早上有点饿感,(空腹练上30分钟左右的瑜伽),喝杯温水,洗漱完给自己做一顿养分早餐(量不大)。
2、正午饭点了,饿感来袭,去吃一顿7、8分饱的午饭,午休30分钟。
3、晚上了有点饿,少吃一些杂粮饼干、生果,避免带着饿感入眠(由于很难睡着)。
科学研究标明人体每天从三餐摄入的养分份额分别是40%、40%、20%,而确保这些养分的摄入,咱们需求每天摄入适量的生果、蔬菜、谷物和蛋白质。
三餐引荐调配:
早餐:多吃五谷和生果,多喝水(弥补水分,身体一晚上的处理,需求很多水,协助排除)
午饭:多吃蔬菜,进食一些肉类(需求进行午睡不易太饱,以免肠胃难过,能够进食小量,午睡后,再吃一些或许下午茶)
晚餐:不易进食难消化,或许对身体欠好的(晚上不易吃姜)
起居有常
何为子午觉:
子时:23:00~01:00;午时:11:00~13:00;
夜半子时为阴阳大会,水火交泰之际,称为“合阴”,它是一天中阴气最重的时分,也是睡觉的最佳时机,子时之前入眠有利于养阴;日间午时也是阴阳交会的时分,阳气最盛,称为“合阳”,此刻午睡有利于养阳。
子午觉的原则是子时大睡,午时小憩,即晚上在子时之前(23:00之前)最好入眠,对于不得不从事熬夜作业的人,与其一直熬到凌晨3、4点,不如在子时这段时刻睡上一会儿,由于这段时刻的睡觉效率远远超越其他时刻段,夸张点说一分钟等于一小时。午觉则只需在午时(11时~13时)歇息30分钟左右即可,由于此刻阳气盛,作业效率最好,午睡时刻过长,不仅糟蹋宝贵的时刻,而且会扰乱人体生物钟,影响晚上睡觉,可是午睡一定要睡,即便睡不着,也要闭目养神,这样有利于人体阴阳之气的正常交接。
在作息中,子午觉对健康极为重要,它仍是一种不花钱的摄生办法,睡好子午觉,你的身体多了一层保障了。
不妄作劳
不妄作劳,结合新时代有不一样的解读,不要忘记劳动,即要坚持运动,也不要过于劳动,即不要运动过量。
由于程序员的作业性质,绝大部分程序员是长时刻对着电脑作业的,加上某些公司存在加班文化,久坐的时刻就更加延长了。所以导致了很多比如腰椎盘杰出、颈椎病、肩周炎、腰肌劳损、圆肩驼背等作业病
运动健身无处不在,无妨利用瑜伽垫+4平米+Keep就能够在家里创始一片健身的空间,当然健身卡能提供更丰富的挑选,而能否坚持完全取决于咱们自己。而坚持两字包含了深不见底的学识。
习气的力气
食饮有节,起居有常,不妄作劳==>故能形与神俱,而尽终其天年,度百岁乃去。
饮食、作息、运动三者休戚相关,相得益彰。三分练,七分吃,充足睡觉不丢掉。如果到这儿,你已经对它们的认知更进一步了,接下来我么来枚举一下围绕着这三个方面的10个小习气:
1.早上空腹一杯温水,减轻肠胃的负累。
2.按时吃饭,越忙越要好好吃饭。
3.吃饭只吃七、八分饱,键肠胃。
4.切勿暴饮暴食,晚上少吃,尤其是油腻食物。
5.每天揉3~8分钟足三里***,能够健脾胃。
6.正午(午时)午休半小时,夜间23:00(子时)前入眠。
7.每作业1~2小时,动身走动倒杯水,再忙也要喝水。
8.将运动融入作业中,每天守时做做运动(平板支撑、颈椎操等),10~30分钟即可。
9.下班后适量地健身运动,越忙越要坚持运动。
10.坚持做上面9条。
将上面的作业坚持做上21天,我相信你一定能够感知到习气的力气。
重点要指出,现在大多数作业都需求久坐,尤其是程序员,要养成守时活动颈椎和腰椎的习气,坚持健身运动,而这些完全能够融入到作业和日子的空隙中。不要为了节约时间短的半小时去拼命作业,也不要吝啬花上15分钟去吃一份有养分的早餐。这些时刻终究会通过提高作业效率来弥补上。不可否认,实际中那些作业忙得不可开交、却依然注重饮食且投入1~2小时到健身中的职场精英早已经养成了这些习气。

美团技术四面经历

志在指尖创始人-谭科阅读(3780)

美团我是在拉勾网上投的简历,之前也投过一次,简历都没通过删选,后来让学姐帮我改了一下简历,从头投另一个部分,获得了面试机会。10月23日中午HR打电话过来预约了下午4点半面试,说会在线写代码,让我预备好网络环境。
成果5点半还没打电话过来,被放鸽子。与hr从头交流过后,确认下周一下午再面,可是跟hr交流预约这一套形似在美团并没有什么用。
美团技能一面20分钟
晚7点,由于想到下周一才面试,我刚预备出去打个羽毛球,北京的电话就来了。面试官各种抱愧,说开会延迟了。
1、毛遂自荐
说了许多遍了,很流通捡要点介绍完。
2、问我数据结构算法好不好
挺好的(其实心还是有点虚,不过最近刷了许多题也只能壮着胆子充胖子了)
3、找到单链表的三等分点,假如单链表是有环的呢
用快慢指针,一个走一步,一个走三步。假如有环,先判别环在哪,找最终一个节点,然后用之前的无环的做法
4、讲一下项目的架构
我要点讲了MVC
5、说一下你熟悉的规划形式
我要点讲了单例、工厂办法、代理
5、有没有配置过服务器啥啥啥
这个我真不知道,都没听过呢,只能诚实说没有,究竟都没法扯。
一面挺匆忙的,我估计面试官刚开完会还没吃饭呢。他说让我等,或许再找一个同事面我,或许就直接告诉我成果了。从一面面试官的声响和口吻,我判别他一定是个部分老迈,问的规划偏多,后边hr告诉我他就是我要去的部分的老迈。哈哈。
美团技能二面60分钟,详细问答
面完一面正预备出去打羽毛球,北京的电话又来了。(注定这周五参与不了球队活动了!)
二面:跟一面比起来,二面面试官的声响听起来就像是搞技能开发的,果不其然,一个小时的纯技能电话面试!面的特别全面!
1、Spring:有没有用过Spring,SpringIOC、AOP机制与完成,SpringMVC
其实我挺不想被问到Spring的细节的,结构这些我都没有温习不太记住了。所以我对面试官说Spring里边的一些比较重要的机制我了解的还不错,然后我用一个实践的比如把我对IOC、AOP了解讲了一下,他听了说对,了解的不错(难得遇到一个边面试边能给反馈的面试官,好开心)
SpringMVC其实我用过,我就对面试官讲了我的项目中用到的Servlet,jsp和javabean完成的MVC,以及MVC各个模块责任以及每个模块是怎样联络到一起的,最终我补充了一句我想SpringMVC的思想其实跟这个是一样的(他说对的,嘿嘿有反馈真好)
2、多线程:怎样完成线程安全,各个完成办法有什么差异,volatile关键字的使用,可重入锁的了解,Synchronized是不是可重入锁
这儿我就首要讲了Synchronized关键字,还有并发包下面的一些锁,以及各自的优缺点和差异。volatile关键字我首要从可见性、原子性和制止JVM指令重排序三个方面讲的,再讲了一下我在多线程的单例形式double-check中用到volatile关键字制止JVM指令重排优化。
3、调集:HashMap底层完成,怎样完成HashMap线程安全
我讲了一下HashMap底层是数组加单链表完成,Node内部类,add的过程,Hash冲突处理办法,扩容,三种调集视图。HashMap线程安全的完成办法首要讲了HashTable、ConcurrentHashMap以及Collections中的静态办法SynchronizedMap能够对HashMap进行封装。以及这三种办法的差异,功率表现。
4、JVM内存管理,GC算法,HotSpot里边的废物回收器、类加载
JVM内存首要分为五个区,哪些是线程共享的,哪些是线程独享的,每个区寄存什么。GC方面:怎样判别哪些目标需求被GC,GC的办法,MinorGC与FullGC。HotSpotGC算法以及7种废物回收期,首要讲了CMS和G1收集器。类加载:类加载的过程,Bootstrapclassloader-ExtClassloader-AppClassloader,父类托付机制。
5、进程和线程的差异
从调度、并发性、具有的资源和系统开支四个方面答复的。
6、HTTP有没有状况,我说无状况,怎样处理HTTP无状况怎样处理HTTP无状况其实就是怎样进行会话盯梢,有四种办法:URL重写、隐藏表单域、Cookie、Session。
7、JavaIO,NIO,Java中有没有完成异步IO
JavaIO完成的是同步堵塞,它是怎样完成同步堵塞的。我拿了read()办法举例来讲的。NIO完成的是同步非堵塞,我详细讲了一下Selector中的select()办法轮询阐明它是怎样完成多路复用IO的。然后对比了一下他们的功率。面试官或许看我对这一块比较了解,又继续问我Java中有没有完成异步IO,我感觉如同没有,但面试官说有,让我想想,其实这儿我并不清楚啦,所以我就对面试官讲了一下我对Unix中异步IO模型的了解,然后说至于Java里边有没有我真的不太清楚。(他竟然笑了!说你了解是对的,Java里边有没有不重要!哈哈)
8、前端会不会,Ajax是什么,Ajax完成原理
前端我仅仅会用一些js罢了,用过jquery结构,问我Ajax全称是啥,我猜是异步的js和xml。Ajax完成原理其实我也不懂,我就只简略讲了一下它通过XMLHttpRequest目标进行异步查询,Ajax引擎在客户端运转,减少了服务器工作量。
9、让我规划一个线程池
由于我简历中有写到我对多线程、并发这一块了解比较好。所以他老问这方面的题。这个问题由于我之前看过ThreadPoolExecutor的源代码,所以我就仿照那个类的规划思路来想的,详细讲了一下中心池、创立线程能够用工厂办法形式来进行规划、线程池状况、堵塞队列、拒绝策略这几个方面。规划的还算比较周全。
10、讲几个规划形式,哪些当地用到了,为什么要用
单例形式,jdk中的getRuntime();工厂办法形式,ThreadPoolExcutor用到ThreadFactory;观察者形式:java.util包下面的Observable和Observer。最终首要讲了一下工厂办法形式的使用场景。
11、Mysql优化、索引的完成
我从数据库规划优化和查询优化两方面讲的。索引B+树完成,InnoDB和MyISAM主键索引的完成差异,一个集合一个非集合。
12、事务的阻隔等级
四种阻隔等级,或许会出现哪些反常,mysql中默认等级。
13、有没有用过Hibernate、mybatis、git
这个简略讲一下就好,分别是干什么的
14、Linux
我说这个本科学过,可是很久没用,命令忘光了。他说没事,考你几个简略的:cd、ls、dir(真的是简略的)
15、算法题
从10万个数中找最小的10个,时刻复杂度分析(最大堆,考虑内存)
从一个有正有负数组中找连续子数组的最大和,时刻复杂度分析(动态规划)
满二叉树第i层有多少个节点,n层的满二叉树共有多少个节点
总算到我提问环节了
1、你们是什么部分(他说是中心部分,大数据研制)
2、我对高并发和负载均衡挺有兴趣的,可是我平常在校园也没有这个环境让我在这方面有所体会,那你主张我目前能够怎样学呢(他说这的确是不太好学,只能看些理论和他人的博客,今后工作中才干渐渐学)
3、中间件详细是做什么的,是处理高并发和负载均衡吗(他说差不多是的,然后他说我们这个部分不是中间件,是大数据部分啊,我说恩我知道)
最终没啥问题了,他让我坚持电话畅通。
这一面面完,口干舌燥,我一度置疑他或许不知道我是在应聘实习生的岗位。有太多要总结的了,放在总结的当地一起讲吧。
美团技能三面25分钟
面试官说是他是另外一个部分的,需求进行穿插面试。
1、MySql优化
2、说下项目做了些什么,架构之类的
3、在collabedit上在线写代码,题目很简略是编程之美上的原题,一个有序的整数数组,输出两个数,使它们的和为某个给定的值。之前做过很快写好,然后给他讲思路。他继续问假如数组无序怎样办,先排序。
4、两个文件,每个文件中都有若干个url,找出两个文件中相同的url(用HashMap)
这一面挺简略的,仅仅增加之前面试没有过的在线写代码环节,collabedit后来我才了解,像facebook一些互联网公司长途面试都会用这个在线编辑器写代码,就是文本文档写,没有提示,不能编译运转,跟白板写一样。平常练练手就好。
美团技能HR四面30分钟
三面面试官说他那就是终面,说我过了等hr联络我。万万没想到半小时后的hr面竟然也是技能。
1、毛遂自荐,都四面了还毛遂自荐?!我还以为是单纯的hr面,所以介绍的都是我的性情和生活方面的,成果并不是。
2、问项目,问的特别特别细,技能细节,还有遇到什么问题,怎样处理的,做项目有没有人带,怎样跟他人交流的。
3、数据库优化,假如数据库一个表特别大怎样办数据库优化我就讲了之前讲过许多遍的点,他问一个表特别大怎样办:大表分小表,怎样完成:使用分区表
4、问研究生的科研题目,为什么选这个题,看了一些什么论文(细到问我那些论文是发表在什么期刊上的,作者是哪所校园的),为什么要选这个算法,怎样优化的,试验成果怎样跟他人作对比的,为什么比他人的算法好(一个个问题不断砸过来,我猜我说的那些专业名词他应该不太懂,仅仅判别一下是不是我做的罢了。。)
5、确认实习时刻这一面的确让我感到有压迫感,项目是本科做的,挺久了,一些技能细节上也没太总结,所以问细了我只能连想带编,嘿嘿。科研方面倒还好,上个学期都在弄这个,一些算法的完成和改进、对比都还记住比较清楚,答复的挺流通的,或许这真的就是技能型的hr面吧。

JVM中垃圾回收机制如何判断是否死亡?

志在指尖创始人-谭科阅读(2641)

这节咱们主要讲废物搜集的一些根本概念,先了解废物搜集是什么、然后触发条件是什么、最后虚拟机怎么判别目标是否逝世。
一、前语
咱们都知道Java和C++有一个十分大的区别便是Java有主动的废物收回机制,经过半个多世纪的开展,Java现已进入了“主动化”年代,让运用者只需要重视业务逻辑的开发而不需要担心内存的运用状况。那么咱们为什么还要学习Java的废物收回机制呢?原因很简略:咱们不想止于“增删改查工程师”这样的初级水平,一旦程序发作了内存溢出、内存走漏等问题时,咱们能够用已掌握的常识更好的调理和优化咱们的代码。在学这章节之前,默许大家现已了解并掌握了Java内存运转时的五个区域的功用:办法区、Java堆、虚拟机栈、本当地法栈、程序计数器。还没有了解过的朋友请先看这里:JVM中五大内存区域
二、判别目标是否逝世
客官们能够先想一下,GC(废物收回机制)在整理内存的时候榜首件事要做什么?肯定是要先判别内存中的目标是否现已逝世,也便是再也不会被运用了,然后才会去收回这些目标。判别目标是否逝世一般会有两种办法:引证计数法和可达性剖析。
2.1引证计数法
运用引证计数法,要先给每一个目标中增加一个计数器,一旦有当地引证了此目标,则该目标的计数器加1,假如引证失效了,则计数器减1。这样当计数器为0时,就代表此目标没有被任何当地引证。这种办法完成简略,判定功率也很高,在大部分状况下都是一个比较不错的办法。可是在Java虚拟机中并没有选用引证计数法来管理内存,其主要原因是它很难解决目标之间彼此引证的问题,假如两个对应相互引证,导致他们的引证计数都不为0,最终不能收回他们。咱们来举个比方
classPerson{publicPersonlover=null;//界说一个爱人privateStringname=””;//名字Person(Stringname){this.name=name;
}
}publicclassDemo{publicstaticvoidmain(String[]args){
Personliangshanbo=newPerson(“梁山伯”);//创建一个人物:梁山伯Personzhuyingtai=newPerson(“祝英台”);//创建一个人物:祝英台liangshanbo.lover=zhuyingtai;//设置梁山伯的爱人是祝英台zhuyingtai.lover=liangshanbo;//设置祝英台的爱人是梁山伯}
}
其间梁山伯和祝英台两个目标相互引证,因而假如运用引证计数法来判别目标是否逝世的话,废物收回机制是不能收回这两个目标的。
2.2可达性剖析算法
在大部分干流言语中都是经过此办法来判别目标是否存活的,这个算法的思维是经过一系列被称为“GCroot”的目标作为开始点,从这些节点开始向下搜索,走过的路径叫做引证链。假如一个目标没有经过引证链衔接到GCroot节点,则证明此目标是不可用的,如下图所示,GCroots是根节点,凡是能经过引证链衔接上GCroot的Object1,2,3,4都是被运用的目标。可是Object5,6,7却不能经过任何办法衔接上根节点,因而判定Object5,6,7为可收回的节点。
GCroot图解
了解了可达性剖析法,你或许又会问了GCroot目标是什么?在JAVA言语中,能够作为GCroot的目标包含以下几种:
虚拟机栈(栈帧中的本地变量表)中引证的目标。
办法区中类静态属性引证的目标。
办法区中常量引证的目标。
本当地法栈中JNI(JavaNativeInterface)引证的目标。
以上四种不需要死记硬背,因为办法区、虚拟机栈和本当地法栈中保存了类中和办法中界说的变量的引证,既然是自己界说的变量,所以肯定是有用的。
2.4“引证”是什么
咱们知道java中将数据类型分为两大类:根本类型和引证类型。java中引证的界说是:假如reference类型的数据中存储的数值代表的是另一块内存的开始地址,就称这块内存代表着一个引证。举个比方:
Personp=newPerson();
上面代码的写法咱们常常见到,其间等号后边的newPerson();是实在的目标,所有的内容都保存在java堆内存中,而等号前面的p仅仅实在内容的一个代称,保存在虚拟机栈内存中,它存储的仅仅一个地址,是newPerson();在堆内存中的开始方位,因而p便是一个引证。
依照这种了解,java的目标只能够分为被引证和没有被引证两种状况。可是在JDK1.2之后,java对引证的概念进行了扩充,分为强、软、弱、虚四种引证,且强度依次逐步下降。
强引证:即咱们常常看到的引证办法,如在办法中界说:Objectobj=newObject();,实在的目标“newObject()”保存在java堆中,其间“obj”代表了一个引证,寄存的是java堆中“newObject()”的开始地址。只需引证还在,废物搜集器就不会收回掉被引证的目标。
软引证:是用来描绘一些有用但非必须的目标,咱们能够运用SoftReference类来完成软引证。对于软引证相关着的目标,在体系将要发作内存溢出异常之前,会把这些目标列进收回规模之中。假如收回之后内存仍是缺乏,才会报内存溢出的异常。
弱引证:是用来描绘非必须的目标,运用WeakReference类来完成弱引证。它只能生存到下一次废物收回发作之前,当废物收回机制开始时,无论是否会内存溢出,都将收回掉被弱引证相关的目标。
虚引证:最没有存在感的一种引证联系,能够经过PhantomReference类来完成。存在不存在简直没影响,也不能经过虚引证来获取一个目标实例,存在的仅有目的是被废物搜集器收回后能够收到一条体系通知。
咱们能够经过代码来操控目标的“强脆弱虚”四种引证,有利于JVM进行废物收回。那么知道了上面的常识后,咱们来探究一下目标是否会逝世?
2.5目标是否逝世
??之前提到过,经过可达性剖析后,找到的不可达目标会被废物搜集器收回,那么,不可达目标必定会被收回吗?答案是不必定。这时候他们处于“死缓”的阶段,假如非要“上诉”,也是有或许被无罪释放的。他们是怎么自救的?在可达性剖析后发现一些目标没有跟GCroot相衔接的引证链,该目标会被进行一次符号,然后进行筛选,筛选的条件是判别该目标有没有必要履行finalize()办法(此办法每个目标默许都有),但假如目标没有重写finalize()办法或许目标的finalize办法现已被虚拟机调用过一次了,则都将视为“没有必要履行”,废物收回器能够直接收回。
??(此段是自我解救的过程,不是重点了解即可)假如该目标被判定有必要履行finalize()办法,那么虚拟机会把这个目标放置在一个F-Queue的行列中,然后由一个专门的Finalizer线程去履行这个目标的finalize()办法。咱们能够在这个办法中进行目标的“自我解救”,即从头与引证链上的任何一个目标建立相关就能够了,比方把this赋值给某个类的变量,或许目标的成员变量,那么在第二次符号时它将被移除“即将收回”的集合,下面咱们看一个案例来了解。
/**
*@author编程开发分享者
*@Date2020/3/1610:51
*/publicclassFinalizeEscapeGC{/**
*常识点回忆:
*1.办法区中寄存的是类的根本信息、静态变量、编译后的代码、常量池
*2.GCroot能够是办法区中静态变量引证的目标
*3.一个目标的finalize()办法最多只会被体系主动调用一次。
**///创建一个静态变量publicstaticFinalizeEscapeGCSAVE_HOOK=null;@Overrideprotectedvoidfinalize()throwsThrowable{super.finalize();
System.out.println(“程序履行了finalize()办法”);
SAVE_HOOK=this;//将自己赋值给一个静态变量完成自我解救,衔接上了GCroot(细品常识点回忆)}publicstaticvoidmain(String[]args)throwsInterruptedException{
SAVE_HOOK=newFinalizeEscapeGC();//榜首次预备杀死目标SAVE_HOOK=null;//将目标置空,按理说会被GC收回,但此目标完成了finalize()办法并完成了自我解救System.gc();//履行GCThread.sleep(500);//因为Finalizer线程优先级比较低,因而短暂休眠主线程等等它if(SAVE_HOOK!=null){
System.out.println(“哈哈哈,我还活着”);
}else{
System.out.println(“No,我哏儿屁了”);
}
System.out.println(“————————–“);//第二次预备杀死目标(跟上面代码一样)SAVE_HOOK=null;//将目标置空,此时finalize()办法现已主动履行过一次了System.gc();//履行GCThread.sleep(500);//因为Finalizer线程优先级比较低,因而短暂休眠主线程等等它if(SAVE_HOOK!=null){
System.out.println(“哈哈哈,我还活着”);
}else{
System.out.println(“No,我哏儿屁了”);
}
}
}
运转成果:
自我解救运转成果
留意:根据《深化了解Java虚拟机》中解说这种自我解救的办法运转价值昂扬,不确定性大,无法保证各个目标的调用次序,因而这一常识点仅作了解即可。
2.6收回办法区
因为咱们常常用的HotSpot虚拟机规定办法区也能够称为永久代,因而很多人以为在办法区中是没有废物搜集的,其实是有的,只不过搜集废物的“性价比”十分低。在堆中,尤其是新生代,废物搜集一般能够收回70%~95%的空间,而永久代的废物搜集功率远低于此。永久代的废物搜集主要收回两部分内容:抛弃常量和无用的类。
收回抛弃常量:当前体系中没有任何目标引证常量池中的某个常量,则一旦发作内存收回,假如有必要,该常量就会被体系整理出常量池。
收回无用的类:要满意三个条件才能证明某个类是无用的,1.类的实例都现已被收回了。2.加载该类的ClassLoader也被收回了。3.该类对应的java.lang.Class目标没有在任何当地被引证。留意:满意以上三点的类仅仅说能够被收回,但并不像目标一样必定会被收回,是否进行收回能够运用虚拟机供给的参数来操控。很多运用反射、动态代理等频频自界说ClassLoader的场景都需要虚拟机具有类卸载功用,以保证永久代不会溢出。

SqlServer检查死锁并解锁

志在指尖创始人-谭科阅读(3514)

-查询哪些表被死锁
selectrequest_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName
fromsys.dm_tran_lockswhereresource_type=’OBJECT’
–查询后会返回一个包括spid和tableName列的表.
–其间spid是进程名,tableName是表名.

–查询主机名
execsp_who2’xxx’
–xxx便是spid列的进程,检索后会列出很多信息,其间就包括主机名.

–通过spid列的值进行关闭进程.
declare@spidint
Set@spid = xxx–锁表进程
declare@sqlvarchar(1000)
set@sql=’kill ‘+cast(@spidasvarchar)
exec(@sql)

Glide基本用法

志在指尖创始人-谭科阅读(3136)

Glide基本用法
Glide.with(this).load(url).into(imageView);
1.with()
得到RequestManager,调用Glide.with()办法用于创立一个加载图片的实例。
假如传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会中止。
假如传入的是Activity或许Fragment的实例,那么当这个Activity或Fragment被毁掉的时候,图片加载也会中止。
2.load()==RequestManager.load()
最终load()办法返回的其实便是一个DrawableTypeRequest目标
3.into()
图片加载办法
4.Glide缓存机制
Glide缓存的完成使用的是LruCache算法。

技术事故复盘,程序员应该学到什么?

志在指尖创始人-谭科阅读(3553)

每一次事故都是在倒逼技术团队生长,没有谁能保证不写Bug不出错,我们要做的,是在事故发作以后,找到问题的本源,及时填坑止损。
清晨,有网友称拼多多呈现严重Bug,100元无门槛券用户能够随意领取并停止消费。大家争相传播,大半夜的都起来领券,有的用户以至领取了上千张。机灵的用户,以最快的速度花掉了优惠券,比方给中国挪动充值。
拼多多清晨回应,“有黑灰产团伙经过一个过时的优惠券破绽盗取数千万元平台优惠券,停止不合理牟利。针对此行为,平台已第一时间修复破绽,并正对涉事订单停止溯源追踪。同时我们已向公安机关报案,并将积极配合相关部门对涉事黑灰产团伙予以打击。”
随后,拼多多发言人表示,实践最终资产损失或低于千万钱。
这个事情发作后,在技术圈炸开了锅,可能是源于传言的“一个bug可能给公司带来200亿的损失”。
作为程序员,我更关怀的是,这个bug到底是怎样来的呢?依据市场传言,我们大致能够得到如下的一些线索。这些线索的真实性还有待考证,或许并不是这次事情的真实状况,但是这也无妨碍我们经过这些线索,来讨论一下这起事故给我们带来的启示。
●好多人羊毛弄了几十万;
●这张券是测试券;
●系统在清晨自动上线测试券;
●运维发现系统爆了,超越了阈值;
●当事人手动下线了测试券;
●手动下线的测试券,早上八点又上线了。
这些端倪看起来能够合理地解释一个严重bug的部署和运维。从这些端倪中,除了优惠券自身的设计问题,我们也能够看到运维的紊乱。测试券怎样可以上线呢?系统爆表了,为什么没有跟进风险防备措施?手动下线了的测试券,怎样又可以重新上线了?为什么上线、下线优惠券操作这么草率?假如一个软件系统是这样的运维程度,出问题是迟早的事情。假如还没出问题,只能说运气太好。
优惠券的设计问题
第一个吸收我们的问题是,“好多人羊毛弄了几十万”。这就意味着,一个人能够领用上千张优惠券。好多人这么操作,阐明无门槛券的领用,技术门槛极低。
普通的优惠券,相似于折扣券,都有运用门槛,比方买100优惠20元。无门槛券,望文生义,就是没有运用门槛的优惠券,100元的优惠券能够买100元的商品,简直同等于现金。由于无门槛券相似于现金,它和普通的优惠券就有严重区别。
先不去管羊毛党,拼多多号称有3亿用户,假如每个用户都合法合理地领用100元无门槛券,这就需求300亿钱。账户注册,简直是零门槛,假如微信10亿用户合法合理地注册、领用无门槛券,给手机充个值,这就需求1000亿钱。
截至昨日,拼多多市值接近230亿美圆,折合钱也就1600亿的样子。100元无门槛券随意领,这看起来像是要拆了公司给大家发奖金的姿势。这肯定不是无门槛券的预期。
随意领的无门槛券,怎样看都不是一个合格的商业设计。最最少,定个数量上限吧,大家抢完就没了,几百万送就送了。送几百个亿,不契合正常的商业逻辑。
普通而言,即使是普通优惠券的领取都有很多附加的条件。比方说,一个账户只能领取一次,或者只要新账户能够领取。而账户的认证,也要有很多的平安措施,比方绑定手机号,绑定设备,运用平安衔接等措施。账户的认证和管理,是一个效劳网站最最根本的功夫。假如一个人能够领用上千张优惠券,那么账户管理的这个根本功,不能算及格。账户的管理程度假如不及格,这个网站的风险比我们想象得还要糟糕。
这么糟糕的账户管理,这么糟糕的商业设计,太出乎人的预料,不契合正常的逻辑。所以,我比拟认同这只是一个测试券,不应该呈现在正常运营的系统中。而假如真是测试券的问题,暴露的就是软件研发和运维的紊乱。
紊乱的研发和运维
一个测试券,竟然自动上线;手动下线后,又自动上线。这样的产品发布流程匪夷所思。一项功用的出炉,要经过设计、完成、评审、测试、审批,才干够走到正式的系统中。这些环节,只需有一个环节发挥了作用,测试券都不可能上线,更不可能自动上线。
上线后,还要有持续的风险监控。假如系统超越了阈值爆掉,运维可以第一时间取得爆表的信息,比方大半夜的,账户异常活泼或者优惠券业务火爆,也可以及时地截断这个风险。
由此可见,对运维人员的合理约束机制,是一个商业公司必需慎重看待的问题。哪能随意一个测试券就能够直接跑到正式的系统中呢?软件的运维,是一个需求特别关注风险管控的环节,特别是软件的质量没有跟上的时分。软件的运维事故,有时分以至会推翻一个行业。
2011年,一个数字证书签发机构,给谷歌签发了多张数字证书。而谷歌历来没有向这个机构申请过数字证书。也就是说,数字证书的持有者并不是谷歌。这个持有者能够冒充谷歌的网站,盗取用户登录信息,包括用户名和密码。这意味着要么这个公司技术水准有问题(黑客攻击),要么这个公司的运维才能有问题(乱发证书)。这个平安问题在2011年8月份被曝光,简直一切的软件巨头立刻宣布封杀这家机构的数字证书。9月份,这家有着很大市场影响力的机构就宣布破产了。
但是,这不是最终结局,数字证书签发行业的厄运才刚刚开端。人们仿佛突然认识到,信息平安不能依赖数字证书机构,一个4000亿美圆市值公司的平安,不能依赖一个40亿美圆市值公司的运营才能。于是,各种各样的新技术在随后几年争相呈现。这些新技术假如普遍运用,将彻底抹掉整个数字证书签发行业。这样的日子,离我们曾经不远了。如今,数字证书签发机构的日子过得都比拟惨淡,卖的卖,散的散。
频频发作平安事故的顺风车,从长期看,也具有相似的性质。相比之下,假如一次事故损失的只要钱,影响可能还算是能够勉强接受的。希望损失的只要钱,但是我对这个希冀并不悲观。
追根究底,运维如此紊乱,普通和软件的质量脱不了干系。一个正派的软件系统,该怎样出品、该怎样部署、该怎样运转、该怎样受权、危机该怎样处置,这些问题都要有设计、有完成、有预案。当事人设计了一个无门槛测试券,就能够在运营系统里跑,而且还能够无限领,这暴露的是背后烂透的软件质量,以及松懈、无序的软件研发流程。我们常说,优秀的软件出自优秀的流程。紊乱的研发流程,很难出品高质量的产品。
我们该怎样做?
无知者无畏,平安问题之所以特殊,就在于它假如不发作,我们或许永远不晓得问题的存在,当然也不晓得问题有多严重。每一次平安危机,都不应该被糜费。假如我们是当事人,有哪些方法能够防止相似的事故呢?
最紧急的事情,就是赶快把账户平安的债给还了。要不然,经过这一次的传播,一大堆的眼睛看好了这块肥肉。黑客攻击的下一波,或许曾经在路上了。
接下来,要尽快思索下面的几件事情。
第一件要做的事情,就是标准研发流程。一流的软件研发流程下出品的产品,再差也不会差到哪儿去。在这个研发流程里,程序员不能单枪匹马地蛮干。需求要讨论,设计要预览,功用要审核,代码要评审,软件要测试,系统要试运营。人人都会犯错误,每一个环节,多几双眼睛盯着,就大幅度减少了犯错误的几率。程序员也能经过研发的流程快速生长,进一步降低错误发作的几率。一个好的制度,能够成就人;一个坏的制度,能够糟蹋人。
第二件要做的事情,代码的平安要注重起来。代码的平安,不都是指黑客入侵。这个无门槛券的领用,就是一个严重的平安事故。反映到代码层面,可能就是账户管理不平安,商业逻辑没有校验,运维受权管理散漫,异常风险没有及时预警。
第三件要做的事情,商业设计要预先推演。即便没有黑客黑产,1000亿钱无门槛优惠券,也不是任何一家商业机构愿意支付的本钱。这是一个幼稚园程度的错误。假如商业逻辑不成立,也就意味着有缺陷的软件需求。树立在破绽百出的需求上的软件,也会是破绽百出的。
第四件要做的事情,改良产品上线的机制。设置产品上线的检查点和流水线,任何一个检查点失效,流水线都要中缀,产品都不能上线。这些检查点包括产品的试运营、功用的审批、配套的监控措施等等。
第五件要做的事情,进步运维的风险防备才能。一个有着3亿用户,230亿美圆市值,运营电子商务的公司,是黑客眼里的肥肉。特别是用户隐私信息和现金流,关系到企业的生死存亡。这种体量的公司,具有优秀的风险防备才能是最根本的请求,而不是如虎添翼的东西。风险的主动检测、及时预警、快速应对,这些措施都要跟得上。
假如无门槛券的商业设计经过推演,软件功用经过讨论,完成代码经过评审,上线经过预演,事故可以及时预警,只需其中的任何一个环节发挥了作用,这次事故都不会这么惨烈!
我了解一个公司不顾一切全速行进,以质量换速度的竞争压力和动力。只是,当我们追求眼下速度的时分,也要思索三尺以外的将来。要不然,这屁股后面累积的债,真会成为怎样甩都甩不掉的大尾巴。

Maven怎么优雅的引进本地jar包

志在指尖创始人-谭科阅读(2596)

问题场景:我们项目中有时分需要引入maven中心仓库没有的jar包,但是又想让这个jar能灵活的跟随项目,nexus私服和开发者本地仓库就不能严厉满足代码的异地移动,此刻就需要将jar随项目代码一同放到VCS中。
解决方法:在项目目录中新建lib目录,将jar放入,然后在pom.xml中增加如下dependency节点:
<dependency><groupId>org.zstackgroupId><artifactId>zstack-sdkartifactId><version>3.4.0version><scope>systemscope><systemPath>${project.basedir}/zstak-sdk-3.4.0.jarsystemPath><dependency>
但很多时分scope为system的时分打包不会主动打包进去的,要增加一个参数才干打包进去的。
假如项目打包时,第三方jar打不进去,导致classNotFounException,需要在build节点中装备jar包静态资源。
对于spring-boot项目则需要在对应的maven打包插件中增加包含systemScope的includeSystemScope装备:
<build><plugins><plugin><groupId>org.springframework.bootgroupId><artifactId>spring-boot-maven-pluginartifactId><configuration><executable>trueexecutable><includeSystemScope>trueincludeSystemScope>configuration>plugin>plugins>build>

UI 工程师,一个为难的角色?

志在指尖创始人-谭科阅读(2316)

同时,这些作业经历和思维方式也一向深深地影响着我,所以即使这终究是个怎么说都会得罪人的论题,我也不得不去勇敢面对。
从一个「认知」说起
一切从事互联网职业的人,都知道有个工种叫做“美工”,当然他还有许多其他的姓名。比方,南边的就喜爱自称“页面仔”,“切图仔”,而tx的就喜爱称为“构建”,意思是构建页面结构的工种。
尽管美工,构建这些姓名看起来没那么巨大上,但也不能说带有轻视,仅仅咱们都不太喜爱这些姓名。并且,早些年真正的美工的作业,是可以从规划到完成一手包办的(现在称为全栈规划师)。
那么,这个岗位从什么时候开端变得有点low了呢?
这可能要从《网页重构》这本书,以及这个岗位的诞生开端。
重构,就意味着推翻过去的东西,从头构建新的规矩准则。美工,因为参与的流程比较长,所以也不可避免地难以做到每个环节都很完美,乃至很糟糕(全栈工程师?呵呵)。
所以导致的成果便是,很多本质很一般的从业人员乘着互联网的大潮,进入了美工这个岗位,最后规划规划做欠好,代码代码写欠好。最终留给人的印象便是:美工都在做一些粗制滥造的东西。
因为这个角色的title实在太多,我仍是统一用UI工程师比较好,至少是个比较新的title吧。
既然是新的title必然会有些新的定位,以tx为例,许多部分的UI工程师也都归到了T族(技能族)的通道中(从前有一段时间是在规划族)。
但是,尽管职级通道区分到了技能族,但编制往往是在规划部分,或者是跟着产品线走。那么规划部分中的UI工程师,就成了规划师中最懂代码,程序员中最懂规划的一拨人了。
这种略微有点错位的身份关系,也曾让咱们苍茫。说是规划师吧,也做不出像样的规划稿;说是工程师吧,只做些页面搞搞动画好像也谈不上工程。
唯一一个经常被咱们挂在嘴边的词便是“用户体会”,但用户体会又是个很大的领域,咱们能掌握的也只有页面的功能,酷炫的动画等等。
这些东西确实可以从某种程度上提高体会,但终究有多大效果,很难去量化。
最近几年,在各种JS结构风生水起的大环境下,更是没有太多人乐意注重UI方面的东西,注重前端职业里这些对像素有特别偏好的人了。
我自己也有这样的趋势,当触摸了更全面的研发流程之后,就很难坚持对UI细节以及从前寻求的极致用户体会的注重度了。
这或许也恰恰阐明,对于某些类型的产品或某些阶段的产品来说,UI细节没那么重要。
而对于注重用户体会的用户体会规划部来说,隶属于规划部的编码人员也较难受到注重和提拔。
这便是UI工程师的窘境。
如果你想走出这个窘境,转行做PHP开发是一个不错的选择。PHP中文网上有很多的免费课程,可以先自学一段时间看看。

信号量Semaphore

志在指尖创始人-谭科阅读(2870)

Semaphore也是一个同步器,和前面两篇说的CountDownLatch和CyclicBarrier不同,这是递增的,初始化的时分能够指定一个值,但是不需求晓得需求同步的线程个数,只需求在同步的中央调用acquire办法时指定需求同步的线程个数;
一.简单运用
同步两个子线程,只要其中两个子线程执行终了,主线程才会执行:
packagecom.example.demo.study;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Semaphore;
publicclassStudy0217{
//创立一个信号量的实例,信号量初始值为0
staticSemaphoresemaphore=newSemaphore(0);
publicstaticvoidmain(String[]args)throwsException{
ExecutorServicepool=Executors.newFixedThreadPool(3);
pool.submit(()->{
System.out.println(“Thread1—start”);
//信号量加一
semaphore.release();
});
pool.submit(()->{
System.out.println(“Thread2—start”);
//信号量加一
semaphore.release();
});
pool.submit(()->{
System.out.println(“Thread3—start”);
//信号量加一
semaphore.release();
});
//等候两个子线程执行终了就放过,必需要信号量等于2才放过
semaphore.acquire(2);
System.out.println(“两个子线程执行终了”);
//关闭线程池,正在执行的任务继续执行
pool.shutdown();
}
}
这个信号量也能够复用,相似CyclicBarrier:
packagecom.example.demo.study;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Semaphore;
publicclassStudy0217{
//创立一个信号量的实例,信号量初始值为0
staticSemaphoresemaphore=newSemaphore(0);
publicstaticvoidmain(String[]args)throwsException{
ExecutorServicepool=Executors.newFixedThreadPool(3);
pool.submit(()->{
System.out.println(“Thread1—start”);
//信号量加一
semaphore.release();
});
pool.submit(()->{
System.out.println(“Thread2—start”);
//信号量加一
semaphore.release();
});
//等候两个子线程执行终了就放过,必需要信号量等于2才放过
semaphore.acquire(2);
System.out.println(“子线程1,2执行终了”);
pool.submit(()->{
System.out.println(“Thread3—start”);
//信号量加一
semaphore.release();
});
pool.submit(()->{
System.out.println(“Thread4—start”);
//信号量加一
semaphore.release();
});
semaphore.acquire(2);
System.out.println(“子线程3,4执行终了”);
//关闭线程池,正在执行的任务继续执行
pool.shutdown();
}
}
二.信号量原理
看看下面这个图,能够晓得信号量Semaphore还是依据AQS完成的,内部有个Sync工具类操作AQS,还分为公平战略和非公平战略;
结构器:
//默许是非公平战略
publicSemaphore(intpermits){
sync=newNonfairSync(permits);
}
//能够依据第二个参数选择是公平战略还是非公平战略
publicSemaphore(intpermits,booleanfair){
sync=fair?newFairSync(permits):newNonfairSync(permits);
}
acquire(intpermits)办法:
publicvoidacquire(intpermits)throwsInterruptedException{
if(permits<0)thrownewIllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
}
//AQS中的办法
publicfinalvoidacquireSharedInterruptibly(intarg)
throwsInterruptedException{
if(Thread.interrupted())thrownewInterruptedException();
//这里依据子类是公平战略还是非公平战略
if(tryAcquireShared(arg)<0)
//获取失败会进入这里,将线程放入阻塞队列,然后再尝试,还是失败的话就调用park办法挂起当前线程
doAcquireSharedInterruptibly(arg);
}
//非公平战略
protectedinttryAcquireShared(intacquires){
returnnonfairTryAcquireShared(acquires);
}
finalintnonfairTryAcquireShared(intacquires){
//一个无限循环,获取state剩余的信号量,由于每调用一次release()办法的话,信号量就会加一,这里将
//最新的信号量减去传进来的参数比拟,比方有两个线程,其中一个线程曾经调用了release办法,然后调用acquire(2)办法,那么
//这里remaining的值就是-1,返回-1,然后当前线程就会被丢到阻塞队列中去了;假如另外一个线程也调用了release办法,
//那么此时的remaining==0,所以在这里的if中会调用CAS将0设置到state
//
for(;;){
intavailable=getState();
intremaining=available-acquires;
if(remaining<0||compareAndSetState(available,remaining))
returnremaining;
}
}
//公平战略
//和上面非公平差不多,只不过这里会查看阻塞队列中当前节点前面有没有前驱节点,有的话直接返回-1,
//就会把当前线程丢到阻塞队列中阻塞去了,没有前驱节点的话,就跟非公平形式一样的了
protectedinttryAcquireShared(intacquires){
for(;;){
if(hasQueuedPredecessors())
return-1;
intavailable=getState();
intremaining=available-acquires;
if(remaining<0||compareAndSetState(available,remaining))
returnremaining;
}
}
再看看release(intpermits)办法:
//这个办法的作用就是将信号量加一
publicvoidrelease(intpermits){
if(permits<0)thrownewIllegalArgumentException();
sync.releaseShared(permits);
}
//AQS中办法
publicfinalbooleanreleaseShared(intarg){
//tryReleaseShared尝试释放资源
if(tryReleaseShared(arg)){
//释放资源胜利就调用park办法唤醒唤醒AQS队列中最前面的节点中的线程
doReleaseShared();
returntrue;
}
returnfalse;
}
protectedfinalbooleantryReleaseShared(intreleases){
//一个无限循环,获取state,然后加上传进去的参数,假如新的state的值小于旧的state,阐明曾经超越了state的最大值,溢出了
//没有溢出的话,就用CAS更新state的值
for(;;){
intcurrent=getState();
intnext=current+releases;
if(next<current)//overflow
thrownewError(“Maximumpermitcountexceeded”);
if(compareAndSetState(current,next))
returntrue;
}
}
privatevoiddoReleaseShared(){
for(;;){
Nodeh=head;
if(h!=null&&h!=tail){
intws=h.waitStatus;
//ws==Node.SIGNAL表示节点中线程需求被唤醒
if(ws==Node.SIGNAL){
if(!compareAndSetWaitStatus(h,Node.SIGNAL,0))
continue;//looptorecheckcases
//调用阻塞队列中线程的unpark办法唤醒线程
unparkSuccessor(h);
}
//ws==0表示节点中线程是初始状态
elseif(ws==0&&!compareAndSetWaitStatus(h,0,Node.PROPAGATE))
continue;//looponfailedCAS
}
if(h==head)//loopifheadchanged
break;
}
}

将String类型的json数据转换为真正的json数据

志在指尖创始人-谭科阅读(4740)

问题
在做JavaWeb项目的时分,我们经常需求将Java对象转化为Json数据格式响应到前台页面,但是转化完成之后,看着是Json类型的数据格式,但实际上是字符串类型,在这里说两个办法将String类型的Json转化为真正的Json。
解决办法
1.在服务器端设置MIME类型
在servlet中设置响应的MIME类型,具体代码:
response.setContentType(“application/json;charset=utf-8”);
2.在前端页面中利用Ajax中的$.get()
使用Ajax请求的时分用$.get()办法,在这个办法的参数中规定数据类型
$.get(url,[data],callback(),type)//将最终一个参数指定为json
//例:
$.get(“userServlet”,{username:”zhangsan”},function(data){//data为服务器响应的String类型的Json数据
alert(data.name);
},json);

高逼格程序员指南

志在指尖创始人-谭科阅读(2692)

一.开端准备工作
1.首要,你的电脑不必定要高配置,可是有必要得是双屏,而且越大越好,假如能一个横屏一个竖屏那就更好了。这样,一个用来查资料,一个用来写代码。总之要显得信息量很大,功率特别高。
2.别人要问你在哪学的PHP这么牛X,千万不要说在php中文网学的,必定要说满是自学的!再吹个牛,什么言语都会,无师自通,不论什么编程言语三天就通晓,记住,吹牛的时分千万不要眨眼睛。
3.再次,你的椅子不必定要舒服,可是必定要能够半躺下。
4.然后,要有许多便签,最好是各种颜色的,用来记录每天要完成的业务。尽量沿着电脑屏幕边框贴满,这样,更能显出有许多事情的样子。
5.东西书,机械工业,orelly的,电子工业什么的都能够,能英文就英文,不可影印版的也能够,反正越厚越好,牢记,千万不要放在书架上,必定要半打开状的堆在桌上。
二.从进门开端
1.着装!着装!着装!(重要的事情说三遍)不论你是去实验室,仍是去公司大楼,仍是在小公司的民宅,仍是在自己创业的黑作坊;不管春夏秋冬、白天晚上、刮风下雨、电闪雷鸣、台风龙卷风,一个高逼格的程序员都应该非常介意自己着装!这儿供给给你几点专业的进阶建议,如:
初级装:衬衣+牛仔裤+休闲鞋。
中级装:T恤+宽松短裤+拖鞋。
高级装:背心+宽松大花裤衩+人字拖。
2.举止得体。在走廊或许过道里时,必定要双手插兜,走起路来要像个痞子,即使学的不太像,至少也要看起来有点反社会的气质,如若不可,可试着走文弱天才型geek路线……
3.假如有女生在你背后指指点点,小声嘀咕些什么的时分后,你要先垂头,然后坚持垂头状况,再慢慢回头,坏坏地蔑笑但不要作声,然后快步走开。
4.进门后,记住不要跟任何人打招呼,垂直走向自己的位置,最多路过咖啡机时,就打一杯咖啡,但接下来不要有多余的动作,这样能显示出自己的专心与心无旁骛。
三.坐下就不要再动了
1.坐下以后,姿势需求稍微后仰。这个程序检验的方法是能翘着二郎腿最好了,然后在后仰的情况下低着头,以便看到屏幕,坚持这个姿势一直到下班。
2.粗暴地把电脑前的大堆书推开一个口,要显得男人一点儿。然后摘下电脑上的一个便签,看一眼,记住,不要超越3秒。现在能够开端coding了
3.能不用IDE就不要用。假如实在装不了,不管IDE是什么,必定要调成DOS那种黑色布景的,这点很重要。
4.千万不要用IM东西沟通,千万不要问同事问题,显得自己没有水平,都是自己上网或许查书。
四.必定用高端,不论有用不有用
1.假如写前台界面,就不停地调试后台代码;假如写Java,就在里边混编C;假如写C,就在里边混编汇编。不光要coding,还要时不时的翻出一本什么英文的书翻一翻,看不懂就看看插图,然后扔到面前,假装懂了持续coding。
2.比如C++:switch统统重构成多态;假如有指针,统统改成智能的;C++必定要自己写template;数字是全部要替换成宏的姓名能起多长就起多长;struct就不要呈现了,假如呈现,也必定要用__attriburte__润饰一下;运算都是位操作的;操作符都是重载的;网络都是并发缓冲线程池的;int只用int32_t声明的;承继不用一般的,什么多承继虚承继啊;helloworld也要写捕获异常的;后人一看代码,中间一堆关键字extern,asm,auto,XXXXX_cast,volatile,explicit,register,template,让一般总在敲int,if,else,for的小程序员顿时心生崇拜。
3.想写注释?算了吧。只要两个路线能够选:一,变量名起得巨长无比,看代码就和读英文文章相同顺利,底子不需求加注释。二,代码无比不流畅,加不加注释底子无影响。
五.最终洒脱地离开
1.不管是同事间开玩笑或许发生任何群体性时刻,不要抬头,更不要东张西望,即使地震火灾,也必定要先提交代码再行离开。
2.人走,主机是绝对不能关的。至少要跑个dailybuild,实在不可正在svn提交也勉强算过关,而且要保证周末也能正常运转。
3.《从入门到放弃》或许《颈椎康复攻略》已经又堆到屏幕前了,千万不要整理,必定要显得博学多识。
4.加班是有必要的,不必定要在技术部最终一个走,但必定要让前台啊,市场啊,尤其是PM都走了,你才能够走。
5.走得时分必定要率性,简略。千万不要收拾任何东西。站起来,走出去,好的,就这样。
6.假如走的时分,必定要说句话的话,那就找到那个最苦逼的人,跟他说:你进展太慢了啊,不要老让我等你。

编程我该学前端、后端还是全栈?

志在指尖创始人-谭科阅读(3982)

作为一名开发者,你或许会想:2019年最好的软件开发技术和编程言语会是什么?它们又是怎么被应用在软件开发傍边的?如果你在考虑这个问题,那就来对当地了。
这篇文章将对前端和后端开发技术做一个比照,先从基本的开始,然后逐渐比较它们的不同点,比方对开发技能的要求、开展潜力、职业生涯的开展和薪水,等等。
1、什么是前端开发?
前端开发首要涉及网站和App,用户能够从浏览器上或App屏幕上看到的东西。简单地说,能够从浏览器上或App屏幕看到的东西都归于前端。
网站和移动App的前端
我们就以你现在正在浏览的网页为例。网页上的内容、图片、阶段之间的空地、左上角的图标、右下角的通知按钮,所有这些东西都归于前端。
移动App的前端和网站是相同的。例如,你所看到的内容、按钮、图片,它们都归于前端。别的,由于移动设备的屏幕是能够接触的,所以应用程序对各种触控手势(比方放大/缩小、双击、滑动等)做出的呼应也归于前端,它们是前端的活动部分。
这些东西是由前端开发者开发出来的,他们运用了Ionic、Swift、Kotlin、Bootstrap、Angular、Vue、jQuery、React.js等开发技术。后边我们会更多地介绍这些开发技术。
物联网的前端
任何能够连接到互联网的设备都是物联网设备。你或许会好奇物联网设备的前端会是什么样的。任何一种智能设备,比方智能冰箱、远程POS机、智能手表、智能钱包,它们都需求供给某种界面,这样用户才干操作这些设备。所以,这种界面便是一种交互前言,组成这种界面的元素便是物联网的前端。
但严格来说,物联网设备并没有真正的前端。不过它们都装有固件,与移动App的前端类似。这些固件能够用各种编程言语来开发,比方C言语、C++、Lua、Python或JavaScript。
2、什么是后端开发?
后端开发即“服务器端”开发,首要涉及软件体系”后端“的东西。比方,用于托管网站和App数据的服务器、放置在后端服务器与浏览器及App之间的中间件,它们都归于后端。简单地说,那些你在屏幕上看不到但又被用来为前端供给支撑的东西便是后端。
网站和移动App的后端
网站的后端涉及搭建服务器、保存和获取数据,以及用于连接前端的接口。如果说前端开发者关怀的是网站外观,那么后端开发者关怀的是怎么通过代码、API和数据库集成来提升网站的速度、功能和呼应性。
与前端类似,移动App的后端与网站后端是相同的。为移动App搭建后端有这些选择:云渠道(AWS、Firebase)、自己的服务器或MBaaS(移动后端即服务,MobileBackendasaService)。
后端开发运用Ruby、Apache、Nginx、PHP、MySQL、MongoDB等技术。后边我们会更多地介绍这些开发技术。
物联网的后端
云渠道是物联网后端的一个重要组件。有证据标明,大部分物联网设备极度依靠云服务器,它们通过服务器上传、处理和下载数据。
高端物联网解决方案的后端乃至涉及人工智能和机器学习。
物联网项目的后端渠道包括AmazonIoT、GoogleCloud、MQTTBroker、IFTTT,等等。

如何做好一个企业的网站

志在指尖创始人-谭科阅读(3318)

一、建网站的步骤网站建造需要哪些步骤?怎么才干做好一个企业网站?网站规划
1、网站方案策划(首要是网站定位,功能,界面风格等)2、注册域名3、网站制造(可自己制造,也可挑选专业的网站建造公司)4、购买虚拟主机(或装备独立主机)5、装备域名、主机及调整程序开通网站6、网站内容增加7、网站推行具体流程如下:
(一)域名(DomainName)是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。域名的注册遵从先请求先注册为原则,管理认证组织对请求企业提出的域名是否违反了第三方的权利不进行任何实质性检查。域名可分为不同别,包括域名、二域名、三域名、国家代码域名等。一般企业注册用.com就能够了,尽量挑比较正规的域名商,如新达网络科技等,以防域名商跑路、不稳定等意外状况。
(二)选购主机主机是用来存放网站以及网页的。假如企业有自己的服务器和IP就能够很便利的建站。关于中小型企业和个人能够挑选网络上的虚拟主机ttpwww.gzxina.ne。国内主机速度快,但比较贵,大部分需要备案,而且空间一般比较小;国外主机廉价,且空间大多没有限制,但速度往往比国内主机慢。免费主时机带来许多的隐患,比方空间缺乏、存在广告、带宽会被限制或者是没有数据库。建议能够运用免费的虚拟主机来做测试网页以及个人网页,正式运用的话好仍是运用自己的服务器或者购买正规的主机。
(三)规划网站首要包括确认网站的类型、需求、风格等。必须要把网站的需求充分把握,对网站的内容、风格有一个整体的认知;在前期收集相关的素材,挑选运用的工具和技能,规划网站的整体和细节。规划网站是极其重要的一个环节,不然后期再修正起来往往会事倍功半。(四)建造网站先要明白静态网站和动态网站的概念。静态网站首要是由静态化的页面和代码组成,一般文件名均以htm、html、shtml等为后缀,网页上能够出现各种视觉动态效果,如GIF动画、FLASH动画、滚动字幕等。动态网站则是指网站内容可根据不同状况动态改变的网站,一般状况下动态网站通过数据库进行架构。动态网站体现在网页一般是以以aspx,jsp,asp,php等为后缀。动态网站服务器空间装备要比静态的网页要求高,费用也相应的高,不过动态网页利于网站内容的更新和用户体会,适合企业建站。网络营销
二、建网站的注意事项
目前许多主机运营商都提供自动建站模板,挑选对应的模板即能够快速地建站。即使是较为杂乱的动态网站,也有很多程序能够参阅,如国内运用多的内容管理体系,只要稍加修正便能够运用。可是要想获得具有特征和高质量体会的网站,则需要自己投入很多精力来进行开发。
1.要有丰厚的网站内容:网站就向报纸相同,其内容适当重要,没人愿意会两次看同一份毫无新意的报纸相同。因而,网站的吸引力直接来源于网站的内容,直接影响网站的质量。
2.对客户的个人信息要予以保护:随着互联网的开展,个性化服务也越来越交心,在如此兴旺的今天,我们怎么样赢得客户的尊重与信任适当重要。如,许多网站要求用户先注册为会员,网站收集用户资料,要求用户填写个人信息,这些真正的意图在于什么?
3.页面翻开的速度要快:假如不能保证每个页面下载速度,至少应该保证主页能赶快的翻开,因而,让网页简单化适当重要,尽量将重要的内容放在页以及防止运用很多的图片。页面下载速度是网站留住访问者的关键因素,一般人的耐心是有限的,假如10-25秒还不能翻开一个网页,就很难让人等待了。在国外,现在已经大大盛行运用文字降低了网页的视觉效果,显得有些呆板,但有过专题查询,“网民上网都是为了看什么?”标明网友们上网的时间大多数是看文字资讯。要想在众多网站竞赛中杀出一条血路来,重要的仍是要走差异化的开展路途,而这条路途的为基础的东西就是要对网站进行定制网站建造。这样以来,才干更好的完成这样的一种开展希望,才干更好的完成个性化开展的目标,这条路途尽管艰难,可是方法得当仍是能够做到的。网站以建造营销型网站为宜。因为网站是企业的在线形象展现,一个杰出用户体会度的网站是拉近企业与用户间隔的很好方式。定制营销型网站才干杰出企业特征,提升网络转化率。

OpenCvSharp 通过特征点匹配图片

志在指尖创始人-谭科阅读(4086)

OpenCvSharp经过特征点匹配图片
现在的手游根本都是重复操作,一个动作要等好久,结束之后继续另一个动作.很麻烦,所以动起了自己写一个游戏辅佐的心思.
这个辅佐自身没什么难度,便是经过不断的截图,然后从这个截图中找出预先截好的能代表相应动作的按钮或者触发条件的小图.
找到之后获取该子区域的左上角坐标,然后经过windowsAPI调用鼠标或者键盘做操作就行了.
这里边最难的也便是找图了,因为要精准找图,而且最好能适应不同的分辨率下找图,所以在模板匹配的基础上,就有了SIFT和SURF的特征点找图方法.
在写的过程中查找资料,大都是C++或者python的,很少有原生的C#实现,所以我就直接拿来翻译过来了(稍作改动).C#
SIFT算法
publicstaticBitmapMatchPicBySift(BitmapimgSrc,BitmapimgSub)
{using(MatmatSrc=imgSrc.ToMat())using(MatmatTo=imgSub.ToMat())using(MatmatSrcRet=newMat())using(MatmatToRet=newMat())
{
KeyPoint[]keyPointsSrc,keyPointsTo;using(varsift=OpenCvSharp.XFeatures2D.SIFT.Create())
{
sift.DetectAndCompute(matSrc,null,outkeyPointsSrc,matSrcRet);
sift.DetectAndCompute(matTo,null,outkeyPointsTo,matToRet);
}using(varbfMatcher=newOpenCvSharp.BFMatcher())
{varmatches=bfMatcher.KnnMatch(matSrcRet,matToRet,k:2);varpointsSrc=newList();varpointsDst=newList();vargoodMatches=newList();foreach(DMatch[]itemsinmatches.Where(x=>x.Length>1))
{if(items[0].Distance<0.5*items[1].Distance)
{
pointsSrc.Add(keyPointsSrc[items[0].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[items[0].TrainIdx].Pt);
goodMatches.Add(items[0]);
Console.WriteLine($”{keyPointsSrc[items[0].QueryIdx].Pt.X},{keyPointsSrc[items[0].QueryIdx].Pt.Y}”);
}
}varoutMat=newMat();//算法RANSAC对匹配的成果做过滤varpSrc=pointsSrc.ConvertAll(Point2fToPoint2d);varpDst=pointsDst.ConvertAll(Point2fToPoint2d);varoutMask=newMat();//假如原始的匹配成果为空,则越过过滤步骤if(pSrc.Count>0&&pDst.Count>0)
Cv2.FindHomography(pSrc,pDst,HomographyMethods.Ransac,mask:outMask);//假如经过RANSAC处理后的匹配点大于10个,才应用过滤.不然运用原始的匹配点成果(匹配点过少的时分经过RANSAC处理后,可能会得到0个匹配点的成果).if(outMask.Rows>10)
{byte[]maskBytes=newbyte[outMask.Rows*outMask.Cols];
outMask.GetArray(0,0,maskBytes);
Cv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,matchesMask:maskBytes,flags:DrawMatchesFlags.NotDrawSinglePoints);
}elseCv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,flags:DrawMatchesFlags.NotDrawSinglePoints);returnOpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}
}
SURF算法
publicstaticBitmapMatchPicBySurf(BitmapimgSrc,BitmapimgSub,doublethreshold=400)
{using(MatmatSrc=imgSrc.ToMat())using(MatmatTo=imgSub.ToMat())using(MatmatSrcRet=newMat())using(MatmatToRet=newMat())
{
KeyPoint[]keyPointsSrc,keyPointsTo;using(varsurf=OpenCvSharp.XFeatures2D.SURF.Create(threshold,4,3,true,true))
{
surf.DetectAndCompute(matSrc,null,outkeyPointsSrc,matSrcRet);
surf.DetectAndCompute(matTo,null,outkeyPointsTo,matToRet);
}using(varflnMatcher=newOpenCvSharp.FlannBasedMatcher())
{varmatches=flnMatcher.Match(matSrcRet,matToRet);//求最小最大间隔doubleminDistance=1000;//反向迫临doublemaxDistance=0;for(inti=0;i<matSrcRet.Rows;i++)
{doubledistance=matches[i].Distance;if(distance>maxDistance)
{
maxDistance=distance;
}if(distance<minDistance)
{
minDistance=distance;
}
}
Console.WriteLine($”maxdistance:{maxDistance}”);
Console.WriteLine($”mindistance:{minDistance}”);varpointsSrc=newList();varpointsDst=newList();//筛选较好的匹配点vargoodMatches=newList();for(inti=0;i<matSrcRet.Rows;i++)
{doubledistance=matches[i].Distance;if(distance<Math.Max(minDistance*2,0.02))
{
pointsSrc.Add(keyPointsSrc[matches[i].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[matches[i].TrainIdx].Pt);//间隔小于范围的压入新的DMatchgoodMatches.Add(matches[i]);
}
}varoutMat=newMat();//算法RANSAC对匹配的成果做过滤varpSrc=pointsSrc.ConvertAll(Point2fToPoint2d);varpDst=pointsDst.ConvertAll(Point2fToPoint2d);varoutMask=newMat();//假如原始的匹配成果为空,则越过过滤步骤if(pSrc.Count>0&&pDst.Count>0)
Cv2.FindHomography(pSrc,pDst,HomographyMethods.Ransac,mask:outMask);//假如经过RANSAC处理后的匹配点大于10个,才应用过滤.不然运用原始的匹配点成果(匹配点过少的时分经过RANSAC处理后,可能会得到0个匹配点的成果).if(outMask.Rows>10)
{byte[]maskBytes=newbyte[outMask.Rows*outMask.Cols];
outMask.GetArray(0,0,maskBytes);
Cv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,matchesMask:maskBytes,flags:DrawMatchesFlags.NotDrawSinglePoints);
}elseCv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,flags:DrawMatchesFlags.NotDrawSinglePoints);returnOpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}
}
模板匹配
publicstaticSystem.Drawing.PointFindPicFromImage(BitmapimgSrc,BitmapimgSub,doublethreshold=0.9)
{
OpenCvSharp.MatsrcMat=null;
OpenCvSharp.MatdstMat=null;
OpenCvSharp.OutputArrayoutArray=null;try{
srcMat=imgSrc.ToMat();
dstMat=imgSub.ToMat();
outArray=OpenCvSharp.OutputArray.Create(srcMat);
OpenCvSharp.Cv2.MatchTemplate(srcMat,dstMat,outArray,Common.templateMatchModes);doubleminValue,maxValue;
OpenCvSharp.Pointlocation,point;
OpenCvSharp.Cv2.MinMaxLoc(OpenCvSharp.InputArray.Create(outArray.GetMat()),outminValue,outmaxValue,outlocation,outpoint);
Console.WriteLine(maxValue);if(maxValue>=threshold)returnnewSystem.Drawing.Point(point.X,point.Y);returnSystem.Drawing.Point.Empty;
}catch(Exceptionex)
{returnSystem.Drawing.Point.Empty;
}finally{if(srcMat!=null)
srcMat.Dispose();if(dstMat!=null)
dstMat.Dispose();if(outArray!=null)
outArray.Dispose();
}
}

C#工具类OracleHelper,如何基于Oracle.ManagedDataAccess.Client封装

志在指尖创始人-谭科阅读(7341)

基于Oracle.ManagedDataAccess.Client封装的Oracle工具类OracleHelper,代码如下:
复制代码
usingSystem;
usingSystem.Data;
usingSystem.Collections.Generic;
usingSystem.Configuration;
usingSystem.Text;
usingSystem.IO;
usingOracle.ManagedDataAccess.Client;
//usingSystem.Data.OracleClient;System.Data.OracleClient类曾经不引荐运用
namespaceFly.Util.DataBase

C#
{
///
///Oracle数据库操作类
///
publicstaticclassOracleHelper
{
///
///执行数据库非查询操作,返回受影响的行数
///
///数据库衔接字符串
///命令的类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前操作影响的数据行数
publicstaticintExecuteNonQuery(stringconnectionString,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
OracleCommandcmd=newOracleCommand();
using(OracleConnectionconn=newOracleConnection(connectionString))
{
PrepareCommand(cmd,conn,null,cmdType,cmdText,cmdParms);
intval=cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
returnval;
}
}
///
///执行数据库事务非查询操作,返回受影响的行数
///
///数据库事务对象
///Command类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前事务操作影响的数据行数
publicstaticintExecuteNonQuery(OracleTransactiontrans,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
OracleCommandcmd=newOracleCommand();
PrepareCommand(cmd,trans.Connection,trans,cmdType,cmdText,cmdParms);
intval=cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
returnval;
}
///
///执行数据库非查询操作,返回受影响的行数
///
///Oracle数据库衔接对象
///Command类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前操作影响的数据行数
publicstaticintExecuteNonQuery(OracleConnectionconnection,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
if(connection==null)
thrownewArgumentNullException(“当前数据库衔接不存在”);
OracleCommandcmd=newOracleCommand();
PrepareCommand(cmd,connection,null,cmdType,cmdText,cmdParms);
intval=cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
returnval;
}
///
///执行数据库查询操作,返回OracleDataReader类型的内存结果集
///
///数据库衔接字符串
///命令的类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前查询操作返回的OracleDataReader类型的内存结果集
publicstaticOracleDataReaderExecuteReader(stringconnectionString,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
OracleCommandcmd=newOracleCommand();
OracleConnectionconn=newOracleConnection(connectionString);
try
{
PrepareCommand(cmd,conn,null,cmdType,cmdText,cmdParms);
OracleDataReaderreader=cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
returnreader;
}
catch
{
cmd.Dispose();
conn.Close();
throw;
}
}
///
///执行数据库查询操作,返回DataSet类型的结果集
///
///数据库衔接字符串
///命令的类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前查询操作返回的DataSet类型的结果集
publicstaticDataSetExecuteDataSet(stringconnectionString,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
OracleCommandcmd=newOracleCommand();
OracleConnectionconn=newOracleConnection(connectionString);
DataSetds=null;
try
{
PrepareCommand(cmd,conn,null,cmdType,cmdText,cmdParms);
OracleDataAdapteradapter=newOracleDataAdapter();
adapter.SelectCommand=cmd;
ds=newDataSet();
adapter.Fill(ds);
cmd.Parameters.Clear();
}
catch
{
throw;
}
finally
{
cmd.Dispose();
conn.Close();
conn.Dispose();
}
returnds;
}
///
///执行数据库查询操作,返回DataTable类型的结果集
///
///数据库衔接字符串
///命令的类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前查询操作返回的DataTable类型的结果集
publicstaticDataTableExecuteDataTable(stringconnectionString,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
OracleCommandcmd=newOracleCommand();
OracleConnectionconn=newOracleConnection(connectionString);
DataTabledt=null;
try
{
PrepareCommand(cmd,conn,null,cmdType,cmdText,cmdParms);
OracleDataAdapteradapter=newOracleDataAdapter();
adapter.SelectCommand=cmd;
dt=newDataTable();
adapter.Fill(dt);
cmd.Parameters.Clear();
}
catch
{
throw;
}
finally
{
cmd.Dispose();
conn.Close();
conn.Dispose();
}
returndt;
}
///
///执行数据库查询操作,返回结果集中位于第一行第一列的Object类型的值
///
///数据库衔接字符串
///命令的类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前查询操作返回的结果集中位于第一行第一列的Object类型的值
publicstaticobjectExecuteScalar(stringconnectionString,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
OracleCommandcmd=newOracleCommand();
OracleConnectionconn=newOracleConnection(connectionString);
objectresult=null;
try
{
PrepareCommand(cmd,conn,null,cmdType,cmdText,cmdParms);
result=cmd.ExecuteScalar();
cmd.Parameters.Clear();
}
catch
{
throw;
}
finally
{
cmd.Dispose();
conn.Close();
conn.Dispose();
}
returnresult;
}
///
///执行数据库事务查询操作,返回结果集中位于第一行第一列的Object类型的值
///
///一个已存在的数据库事务对象
///命令类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前事务查询操作返回的结果集中位于第一行第一列的Object类型的值
publicstaticobjectExecuteScalar(OracleTransactiontrans,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
if(trans==null)
thrownewArgumentNullException(“当前数据库事务不存在”);
OracleConnectionconn=trans.Connection;
if(conn==null)
thrownewArgumentException(“当前事务所在的数据库衔接不存在”);
OracleCommandcmd=newOracleCommand();
objectresult=null;
try
{
PrepareCommand(cmd,conn,trans,cmdType,cmdText,cmdParms);
result=cmd.ExecuteScalar();
cmd.Parameters.Clear();
}
catch
{
throw;
}
finally
{
trans.Dispose();
cmd.Dispose();
conn.Close();
conn.Dispose();
}
returnresult;
}
///
///执行数据库查询操作,返回结果集中位于第一行第一列的Object类型的值
///
///数据库衔接对象
///Command类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
///当前查询操作返回的结果集中位于第一行第一列的Object类型的值
publicstaticobjectExecuteScalar(OracleConnectionconn,CommandTypecmdType,stringcmdText,paramsOracleParameter[]cmdParms)
{
if(conn==null)thrownewArgumentException(“当前数据库衔接不存在”);
OracleCommandcmd=newOracleCommand();
objectresult=null;
try
{
PrepareCommand(cmd,conn,null,cmdType,cmdText,cmdParms);
result=cmd.ExecuteScalar();
cmd.Parameters.Clear();
}
catch
{
throw;
}
finally
{
cmd.Dispose();
conn.Close();
conn.Dispose();
}
returnresult;
}
///
///执行数据库命令前的准备工作
///
///Command对象
///数据库衔接对象
///事务对象
///Command类型
///Oracle存储过程称号或PL/SQL命令
///命令参数汇合
privatestaticvoidPrepareCommand(OracleCommandcmd,OracleConnectionconn,OracleTransactiontrans,CommandTypecmdType,stringcmdText,OracleParameter[]cmdParms)
{
if(conn.State!=ConnectionState.Open)
conn.Open();
cmd.Connection=conn;
cmd.CommandText=cmdText;
if(trans!=null)
cmd.Transaction=trans;
cmd.CommandType=cmdType;
if(cmdParms!=null)
{
foreach(OracleParameterparmincmdParms)
cmd.Parameters.Add(parm);
}
}
///
///将.NET日期时间类型转化为Oracle兼容的日期时间格式字符串
///
///.NET日期时间类型对象
///Oracle兼容的日期时间格式字符串(如该字符串:TO_DATE(‘2007-12-1′,’YYYY-MM-DD’))
publicstaticstringGetOracleDateFormat(DateTimedate)
{
return”TO_DATE(‘”+date.ToString(“yyyy-M-dd”)+”‘,’YYYY-MM-DD’)”;
}
///
///将.NET日期时间类型转化为Oracle兼容的日期格式字符串
///
///.NET日期时间类型对象
///Oracle日期时间类型格式化限定符
///Oracle兼容的日期时间格式字符串(如该字符串:TO_DATE(‘2007-12-1′,’YYYY-MM-DD’))
publicstaticstringGetOracleDateFormat(DateTimedate,stringformat)
{
if(format==null||format.Trim()==””)format=”YYYY-MM-DD”;
return”TO_DATE(‘”+date.ToString(“yyyy-M-dd”)+”‘,'”+format+”‘)”;
}
///
///将指定的关键字处置为含糊查询时的合法参数值
///
///待处置的查询关键字
///过滤后的查询关键字
publicstaticstringHandleLikeKey(stringsource)
{
if(source==null||source.Trim()==””)returnnull;
source=source.Replace(“[“,”[]]”);
source=source.Replace(“_”,”[_]”);
source=source.Replace(“%”,”[%]”);
return(“%”+source+”%”);
}
///
///执行存储过程
///
///SqlServer数据库衔接对象
///存储过程名
///存储过程参数
///SqlDataReader对象
publicstaticOracleDataReaderRunStoredProcedure(OracleConnectionconnection,stringstoredProcName,IDataParameter[]parameters)
{
OracleDataReaderreturnReader=null;
connection.Open();
OracleCommandcommand=BuildSqlCommand(connection,storedProcName,parameters);
returnReader=command.ExecuteReader(CommandBehavior.CloseConnection);
returnreturnReader;
}
///
///构建SqlCommand对象
///
///数据库衔接
///存储过程名
///存储过程参数
///SqlCommand
privatestaticOracleCommandBuildSqlCommand(OracleConnectionconnection,stringstoredProcName,IDataParameter[]parameters)
{
OracleCommandcommand=newOracleCommand(storedProcName,connection);
command.CommandType=CommandType.StoredProcedure;
foreach(OracleParameterparameterinparameters)
{
command.Parameters.Add(parameter);
}
returncommand;
}
}
}

C#运用Math.Round办法对计算结果进行四舍五入操作

志在指尖创始人-谭科阅读(5325)

在C#的数值运算中,有时分需求对计算结果停止四舍五入操作,此时就可运用内置办法Math.Round办法来完成四舍五入操作,Math.Round办法有多个重载函数,支持设置有效位数进行四舍五入,假如没有设定有效位数,默许四舍五入到对应有效位数。c#语言的特点是什么
Math.Round办法常用的几个重载函数有:
(1)针对十进制decimal类型数据四舍五入,直接保存整数位decimalRound(decimald);
(2)针对双精度类型double类型数据四舍五入,直接保存整数位(1)针对十进制decimal类型数据四舍五入,直接保存整数位doubleRound(doublea);
(3)针对十进制decimal类型数据,指定保存的小数位数decimalRound(decimald,intdecimals);
(4)针对双精度类型double类型数据四舍五入,指定保存的小数位doubleRound(doublevalue,intdigits);
举例如下:
doublenum=3.446D;
doubleresult1=Math.Round(num);//得到结果为3
doubleresult2=Math.Round(num,2);//得到结果为3.45
decimalnum1=3.446M;
decimalresult3=Math.Round(num1);//得到结果为3
decimalresult4=Math.Round(num1,2);//得到结果为3.45

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载