服务热线:400-889-1636
在线咨询: 
网站建设,网站制作,企业网站建设,网上商城,网站推广,域名注册,求创科技
网站建设,网站制作,企业网站建设,网上商城,网站推广,域名注册,求创科技
首页 求创资讯 软件开发
求创动态行业资讯网站建设网页设计微网站手机网站H5动画系统开发APP开发交互设计微信小程序网站维护
  • 跑腿软件开发,没有你想象的那么简单,跑腿创业者慎入软件研发

    时至2018,跑腿行业的优势与潜力已被很多创业者发掘,新零售的强势发展,让跑腿配送行业一下火了起来,也让越来越多的跑腿创业者关注跑腿软件开发这一块。初过2017年关,上门寻求合作的跑腿创业者与日俱增。说到软件,部分跑腿创业者的想法麒麟科技大体知道一些。跑腿创业者之所以关注跑腿软件开发,是想自己开一家跑腿公司,多数创业者也知道开发跑腿软件和做跑腿行业不同,但是从成本、品牌等方面考虑,想要考察一下软件的研发费用,如果费用不高、难度不大,干脆自己研发。今天麒麟科技想和众跑腿创业者说的就是这件事。跑腿软件研发需要做什么研发跑腿软件首先要成立一家公司,其中的过程就不细说了。其次,除了行政、人事、财务外,还需要招聘相当数量的程序研发人员。最令人头疼的还是程序员的招聘,一线城市自然好说,厉害的程序员很多,当然程序员薪水也很高;如果你所在的是三线城市,那么不好意思,厉害的程序员太少,薪水太低人家也不回来,所以只能溢价招聘,不招20个程序员,你都不好意思说你要开发跑腿软件。接下来说说办公设备,作为程序开发的电脑,不用高配说不过去,一台最少1万打底,再加上办公桌椅、办公室租赁,简单一算就能算出大概。当一切都准备齐全开始研发了,研发的周期很长,哪怕不必要的功能准备日后慢慢开发,也需要几个月的时间开发软件,你要开发的有客户端、配送端、管理后台等,开发之后还要测试,遇到手机耗电量高、软件闪退等问题还要重新修改。研发跑腿软件一定要打好提前量,资金一定要充足,除了岔子一切努力可能付之东流。得之东隅,失之桑榆。注意上文的研发时间,几个月的时间过去了,你做跑腿公司的主业了吗?最佳的跑腿市场发展时期错过了吗?还有机会分跑腿的蛋糕吗?你做出的软件一定好用吗?你懂产品和用户吗?什么时候才应该开发跑腿软件把握市场的航向,抓住用户痛点,找好市场营销点,做好跑腿员招聘,如何让企业规模扩大,找好融资渠道等,才应该是跑腿创业者作为一个企业的灵魂人物该做的事情。至于自己开发跑腿软件,除非一开始你就有大量的资本,或者融资后需要做大自己的品牌,这时才应该去打造自己的跑腿软件。

  • 一个来自19岁的女孩软件开发人员的忠告

    不要担心,这不会是我每天早晨4点起床并跑20公里跑... - '激动人心'的帖子之一,这让人觉得他们需要成为某种超级人类成为一名优秀的开发人员。有些人可能会认为我是一个什么都不做的女孩子,但其实那是因为我没有分享过我日常都在做些什么,也从未说明过我为了成为一名软件开发人员而做过些什么!我是如何进入编程世界的我叫lydia,是一名19岁的生活在斯德哥尔摩的女孩,我是一名JavaScript的开发人员。我在社交媒体上非常活跃,并试图通过展示我在这个社区的生活状态来激励更多人加入科技世界。我15岁时开始编程。我在tumblr上有一个蓬勃发展的健康和生活方式博客,并且随时获得了数以万计的追随者。这是当我开始用常规的html,css和jquery创建自己的响应式布局时,因为我不喜欢我可以购买的主题,所以我决定自己尝试一下!从那里开始,我一直在提高自己的技能,获得更多的知识,并且我对发展的兴趣也在增长。然而,我不知道这已经被认为是编码,我可以为此谋生,我只是喜欢从头开始创建自己的设计,并且看到人们喜欢我制作的布局,并愿意为此付钱。我去了高中,直到我18岁,绝对讨厌它。我觉得我浪费了太多的时间在那些可能无法改善我未来的主题上(看着你,古希腊和拉丁!)。尽管如此,我为我的文凭工作非常努力,在许多个人项目上工作,并一直忙于辅导和支持人!人们形容我是他们见过的最勤劳,最轻松的人,我认为这完美地描述了我的心态。但我们会在稍后回顾!我一直都很独立:18岁时我独自搬到了另一个国家,十几岁的时候我独自旅行,一直忙于改善我的未来。我从来没有感受到做事的压力,因为社会需要我,我一直在做我自己的事情。在我决定不上大学之后,但是让我的110%来编程,我去了佛罗里达州坦帕湾的一个编码训练营3个月。我不必这样做,但它肯定帮助我获得了一些结构,并被其他喜欢编程的人所包围,因为我之前没有这样做。我密集编码,经常脱离我的舒适区(我喜欢),在我的个人项目中付出了很多努力来提高我的编码技能,并学习了许多新技术。你猜怎么了?即使在3个月内,也有一大批招聘人员向我询问是否可以为他们工作。这是在我创建了一个linkedin个人资料后,可以显示我付出了很多努力的工作。作为一个没有任何工作经验的19岁女孩,这种感觉有点令人难以置信。我不明白:他们没有阅读我的LinkedIn个人资料吗?我没有去上大学或什么,为什么会有这么多公司想要我?因为你不学习如何在学校编码。你通过编写程序学习如何编写代码。大多数公司并不在乎你是否有一篇很好的论文,说你在大学学习了程序设计:人们关心你可以证明你的编程技巧是好的,并且你喜欢编写代码。不要误解我的意思。如果你喜欢大学生活,或者只是需要一些更多的生活结构,那么去那里绝对是一个很好的决定。但是,不要感到压力。编程社区可能会很苛刻:因为他们编程的语言,他们彼此讨厌,他们看起来像是正常的2小时睡眠,因为你必须整夜编码,并且吃垃圾食物和坐着整天只是它的方式。情况绝非如此。我的日常生活(工作之外)训练营结束后,我飞回斯德哥尔摩。我非常激动地开始了我人生中的这一新篇章,迫不及待地想要继续发展。那么我现在在一个正常的日子里做什么?我醒来后试图伸展。这听起来像我之前谈到的典型的“励志”博文(他们就像在LinkedIn中无处不在,这让我发疯了),但这是非常重要的。你坐几个小时,如果你没有照顾它,你的身体肯定会受到影响。它也真的让你起床,因为你的心率增加,你的大脑得到更多的氧气。我尝试每天至少观看2小时在线编码课程。我喜欢在线课程,因为我总是学习新事物,并通过看教练轻松编写代码来获得灵感。我尝试通过在侧面的类似项目上工作来给我自己的转折,只是略有不同,所以我不是简单地复制教练正在做的事情。而且,当你只是不想下床睡觉并且仍然觉得自己已经很有成效时,这是完美的;)我尝试在我的个人项目上工作至少4个小时。他们让我感觉超级不舒服。我总是尝试使用以前从未使用过的语言或技术,所以我获得了更多的经验。说实话,这太可怕了!我不会撒谎,并说如果你努力工作,你会到达那里(你会这样做,但这不是重点),但我也很想强调这样一个事实:学习新东西可以成为一个情感过山车。你会感到失望,感觉你永远不会理解它,并且真的质疑你的编码技巧。如果你这样做,恭喜!你是一个正常的人!感觉这些情绪并不是这里的重要部分:你对此做的事情是最重要的部分。研究它,向人们伸出援手,编写自己的堆栈溢出问题(并且成为许多人的英雄),并且继续尝试直到找到解决方案。如果你不这样做,那就完全没问题。过了一段时间之后,你可能会回头看看它,并想“我怎么不能回到那里?!”。我尝试阅读至少2篇文章。我真的很喜欢从不同的角度看待事情。这些文章可以讲述任何事情:如何解决某个编码问题,为什么有时候JavaScript很糟糕,或者最酷的新技术是什么。不要陷入某种心态是很重要的!我尝试解决至少5个codewars卡塔。codewars是你最好的朋友,当你进入编码时,也是你编码数十年的时候!他们提供的问题的解决方案通常非常有用,因为您将学习通过滚动其他人提供的解决方案来改进语法。另外还有一个很大的好处:当你参加你的编码面试时,他们经常会给你提供与codewars上的问题非常相似的问题!我尽量不吃垃圾食品。吃有营养的食物让我非常警觉,最重要的是,快乐!当我有一个非常健康的早餐和午餐时,我感觉更加充满活力和动力,这绝对提高了我的编码能力。不要快速简单地去,但长远来看:你的身体越好,你的头脑越好,你的代码越好!你注意到了什么吗?我一直说“我尝试”。因为当我无法做到这些时,我不会强迫自己做事情。我不想给自己一个不好的感觉,因为我没有参与我的个人项目,或者当我吃过垃圾食品。给我的110%是我的重点,但我是人类的:在某些日子里,我只是不想编码,感觉很累,只想整天看Netflix。这完全没问题!在放松和勤奋之间找到适当的平衡点。这回到了人们对我成为他们见过的最勤劳,最轻松的人的评论:但要想这种心态并不容易!当我整天不工作时,我花了很长时间才感到不舒服。特别是在加入instagram之后:我经常看到那些编码太多的人的帖子,我觉得我也必须这么做,根本没有时间休息一天。但是一旦我开始让放松成为我生活中的重要部分,一切都变得更好。我感到非常快乐,我更有动力去工作了很多。结论通过写这篇文章,我希望能激励一些人也参与到科技世界中来,而且它并不像看起来那么可怕。编程不仅适用于电影中描绘的超级智能超级人物。编程适合任何喜欢创作,喜欢脱离舒适区的人,以及喜欢提升自我的人!总之,我的最后建议是:你真的不需要上大学,只要你真的可以推动自己,展现你的编码热情!总是尽可能地给你110%,并通过让你的名字在那里向世界展示你的能力。然而,总是优先考虑你的健康。睡眠非常重要!感到不舒服并认为自己在编码方面真的很糟糕是不正常的,不要让这让你失望。每个人都会不时地想到这一点。总是提醒自己,你已经走了多远。忘记你有多少改进是很容易的,但现在就比较一个月吧!我可以向你保证,这比你想象的要多得多。不要让其他人让你觉得你编程的语言是一种糟糕的语言。这实际上不是,它很可能非常必要和有用!

  • 当今“低头一族”已被这位大师统治《软件开发工程师》

    简单认识:软件开发工程师是从事软件开发相关工作的人员的统称。 软件开发工程师的技术要求是比较全面的,除了最基础的编程语言(C语言/C++/JAVA等)、数据库技术(SQL/ORACLE/DB2等)、.NET平台技术、C#、C/S B/S程序开发,还有诸多如JAVA SCRIPT、AJAX、HIBERNATE、SPRING、J2EE、WEB SERVICE、STRUTS等前沿技术。证书是中国职业教育资格认证指导中心颁发的专业技能证书。标有证书序列号、证书编号、培训者及证书持有者身份证号码,并盖有全国职业教育管理委员会、中国职业教育资格认证指导中心的证书专用章,证书在全国范围内有效。范围:软件开发工程师一般包括软件设计师、软件架构师、软件工程管理人员和程序编码员等岗位。按照汇编语言,软件开发工程师可以分为java软件工程师、.net软件工程师、c++软件工程师、asp.net软件工程师、PHP软件工程师、JSP软件工程师等。发展方向:(实用开发)或(移动开发);软件开发工程师职业发展方向:产品研发经理、技术经理、高级软件工程师、软件架构工程师或项目经理。走专业道路,可从初级开发人员成长为技术专家,如高级软件工程师、高级开发人员、网站架构设计师等。要成为高级开发人员,有两个方面的知识是必须具备的,一个是专业知识,包括对开发平台/工具的了解,对开发流程的理解和使用(软件工程);另外一个方面就是对客户的商业流程的了解;待积累经验后,可发展成为管理型人才,如产品研发经理。产品研发是二十一世纪企业竞争的主战场。产品研发经理必须面向市场,面向客户,迅速的满足客户的需求,为公司获得核心的竞争力。所以该职业具有很大的发展空间和挑战性;可以走网站运营路线,发展成为网站运营经理。互联网软件开发工程师从事网站运营管理的优势在于他们对网站知识有系统的了解,能够结合运营情况对网站建设给出指导性的建议。待遇及就业前景:一般在3000-10000元,工作两年左右的软件开发工程师月薪一般在4000元,3-5年经验的一般在5000-8000元。作为“朝阳行业”,软件行业的发展虽然也受到了全球金融危机的影响,但就目前的发展形势来看,软件工程专业在未来多年内仍然将是就业形势比较好的专业。2009年就业调查报告显示,软件工程就业率及就业工资水平均居高校各专业前列。这主要源自于软件行业的快速发展和政府经济结构调整而对软件人才的迫切需求,据估计,我国目前存在着80万的软件人才缺口,而对软件人才的需求也以每年20%的速度递增。未来几年,国内外的高层次软件人才仍旧处于供不应求的状态。目前软件工程专业毕业生主要在各大软件公司、企事业单位、高等院校、各大研究所、国防等重要部门从事软件设计、开发、应用与研究工作。有数据表明,我国软件出口规模达到215亿元,软件从业人员达到72万人,在中国十大IT职场人气职位中,软件工程师位列第一位,软件工程人才的就业前景十分乐观。

  • 10条关于2018 年软件开发的预测,不仅仅是区块链

    区块链、NLP、AI驱动的工具、机器学习、无服务器计算和devops创新将在2018年改变开发者的生活。开发人员应该对2018年的机遇感到兴奋,产品和工具围绕着诸如区块链、聊天机器人、无服务器功能和机器学习等技术在现实世界的项目中变得足够成熟。与此同时,许多开发人员会担心,在不影响安全性和性能的前提下,他们将无法更快地交付代码和功能。但这方面也有好消息。对于开发人员来说,2018年的定义是,在抓住转型新机遇的同时,在应对压力的同时,要做得更多,质量更高。以下是有关这些力量将在未来一年如何发挥作用的10个预测。1. 利用区块链的B2B交易进入生产阶段企业已经开始了解从区块链启动的交易中获得的安全性、可靠性和效率。在未来的一年,开发人员将在整个金融服务和制造供应链中实施许多区块链用例。区块链是一种技术,它可以使组织之间的高效、安全、不可变、可信的交易成为可能,而这些交易可能不会完全相互信任,从而消除中介。考虑一家公司从一家离岸制造商订购产品。这些产品通过船运公司发货,通过海关,通过另一家船运公司,最后到达买方。今天,每个步骤的验证和调节主要通过电子邮件和电子表格进行,其中涉及很多人和过程。区块链通过不可撤销的对区块链分类账的更新,消除了手工流及和解,当最少数量的参与者说,"是的,这部分交易发生了。"区块链云服务将带来可伸缩性、弹性、安全性以及与企业系统的预构建集成,使开发人员更容易将重点放在业务用例上,而不是底层的hyperledger fabric实现。2. 聊天机器人经常与顾客和员工进行真正的对话人们已经厌倦了需要多个移动应用程序来做同样的工作,就像三种不同的航空公司应用程序一样,通过不同的方式办理登机手续并获得登机牌。一种更好的方法是提供同样的功能,但是通过手机消息上最流行的应用程序。消息传递有三个具有吸引力的元素:即时、表达性和会话性,不需要培训。由于人工智能和自然语言处理技术的进步,人们将会使用Facebook Messenger、Slack、微信、WhatsApp或像亚马逊Alexa或谷歌Home这样的语音助手,来问问题,并从智能机器人那里得到答案。开发人员使用新的智能的bot构建云服务,可以快速地制造能够理解客户意图、维护会话状态的机器人,并在与后端系统集成的过程中智能地响应。想象一下你在电影中看到的一件连衣裙的图片,然后把照片传给你最喜欢的服装店的机器人,它使用图像识别和人工智能来推荐相似的服装。员工也可能是机器人的巨大受益者,比如询问他们已经离开了多少个假期,提交了一张帮助办公桌的票,或者订购了一台替换的笔记本电脑,在那里,系统甚至知道员工有哪些笔记本电脑符合资格,并且可以根据他们的订单提供状态更新。考虑到对你自己的员工基础的试验更宽容,开发人员可能会首先利用他们的"造人"能力来建立和测试员工面对的机器人。3. 按钮消失了:AI变成了app界面人工智能成为UI,意味着使用应用和服务的同步、请求-响应模型逐渐消失。智能手机仍然是"低智商",因为你必须去接他们,启动一个应用程序,要求做一些事情,最终得到回应。在新一代智能应用程序中,该应用将通过推送通知启动交互。让我们更进一步,使用人工智能的应用程序、机器人或虚拟个人助手将知道该做什么、何时、何地以及如何做。就这样做。两个例子:费用审批程序会注意你的报销模式,开始自动审批费用报告的99%,只会让你注意到需要你注意的罕见报告。分析应用程序了解底层数据,业务用户提出的问题,以及公司其他用户对相同数据集的问题,并且每一天都提供了一个新的见解,分析人员可能没有想到。当组织收集更多的数据时,人工智能可以帮助我们了解需要问哪些问题的数据。开发人员需要弄清楚哪些数据对他们的业务应用程序非常重要,如何从事务中观察和学习,哪些业务决策将从这种主动的人工智能中获益最多,并开始进行试验。嵌入式人工智能可以预测你需要什么,在合适的时间通过合适的媒体发布信息和功能,包括在你需要它之前,并自动完成你今天手动完成的许多任务。4. 机器学习采用实际的、特定领域的用途机器学习正从晦涩的数据科学领域转移到主流应用程序开发领域,这都是因为在流行的平台上可以预先构建模块的可用性,而且在处理大型的历史数据集时,它非常有用。通过机器学习,最有价值的洞察力来自于背景,你以前做过什么,你问过什么问题,别人在做什么,正常的和反常的活动是什么。但是要想有效,机器学习必须在一个领域特定的环境中进行调整和训练,该环境包括它将分析的数据集和它将回答的问题。例如,设计用于识别安全分析师异常用户行为的机器学习应用程序将与设计用于优化工厂机器人操作的机器学习应用程序非常不同,这可能与基于微服务的应用程序的依赖映射的设计非常不同。开发人员需要更加了解领域特定的用例,了解要收集什么数据,应用什么样的机器学习算法,以及要问什么问题。开发人员还需要评估特定领域的SaaS或打包应用程序是否适合给定的项目,因为需要大量的培训数据。使用机器学习,开发人员可以构建智能应用程序来生成建议、预测结果或做出自动化的决策。5. DevOps走向无操作我们都同意devops对于帮助开发人员快速构建新的应用程序和特性非常重要,同时保持高质量和性能。devops的问题是开发人员需要花费他们60%的时间在方程的操作一边,从而缩短开发的时间。开发人员必须集成各种持续集成和持续交付(CICD)工具,维护这些集成,并随着新技术的发布不断更新CI / CD工具链。每个人都有CI,但没有太多的人做CD。开发人员会坚持使用云服务来帮助钟摆在2018年回归开发。这将需要更大的自动化。Docker提供了打包、可移植性以及进行敏捷部署的能力。您需要CD作为Docker生命周期的一部分。例如,如果您正在使用容器,一旦您将代码更改提交给Git,那么构建的默认构件应该是具有新版本代码的Docker映像。此外,映像应该被自动推送到Docker注册表中,并将一个容器从映像部署到devtest环境中。在QA测试和部署到生产之后,应该为您处理容器的编排、安全性和扩展。商业领袖正在向开发者施压,要求他们更快地提供新的创新;devops模型必须为开发人员腾出更多的时间使其成为可能。6. 开源作为一种服务,加速了开源创新的消费开源模式仍然是创新的最佳引擎之一,但实现和维护创新往往过于复杂。例如:您想要一个流数据/事件管理平台,所以您可以转向Kafka。当您开始在规模上使用Kafka时,您必须设置额外的Kafka节点和负载平衡大型Kafka集群,随着Kafka的新版本的发布更新这些集群,然后将此服务与您的其他环境集成起来。您需要容器编排的Kubernetes。平台应该为您的Kubernetes集群服务,而不是为您的Kubernetes集群处理升级、备份、恢复和补丁。Kubernetes每六个星期航行一次,所以这个平台应该有滚动部署和自我修复。您需要为NoSQL数据库提供Cassandra。您应该希望备份(在计划中是增量的或完整的)、补丁、集群、扩展和高可用的Cassandra集群,由平台来管理。开发人员将越来越多地寻找云服务,以便在处理这些技术的操作和管理方面的同时,从开放源码中提供所有的高速创新。7. 无服务器计算的架构在生产中会变得很大无服务器架构的吸引力是显而易见的:当需要基于某个事件执行我的代码时,基础架构被实例化,我的代码被部署和执行,而我只在代码运行的时候被收取费用。假设你想建立一个旅行预订功能来预订/取消航班、酒店和租车。每个操作都可以构建为一个以不同语言编写的无服务器函数,如Java、Ruby、JavaScript和Python。没有应用程序服务器在运行我的代码;相反,只有在需要时,函数才被实例化并在基础结构上执行。对于开发人员来说,将无服务器的函数串在一起执行复杂的事务会带来新的挑战:描述如何将这些函数链接在一起,调试分布式事务,并决定如何在一个函数的链上失败,从而创建补偿事务来取消不适当的更改。寻找云服务和开放源码工具,比如FN项目,通过帮助开发人员轻松地管理服务器功能的编程、组成、调试和生命周期管理,并在笔记本电脑或on - prem服务器或任何云上部署和测试它们,从而繁荣发展。关键是要选择一个提供最大可移植性的无服务器平台。8. 关于容器的唯一问题是"为什么不呢?"容器将成为开发/测试工作的默认值,并成为生产应用程序的常见内容。在开源创新和行业标准的驱动下,希望在安全性、可管理性、编制、监控和调试方面持续改进。容器为驱动现代开发的许多趋势提供了构建块,包括微服务体系结构、云本地应用程序、无服务器函数和devops。容器在任何地方都是没有意义的——例如,当您需要一个更规定性的云平台时,例如集成PaaS或移动PaaS,但是这些更高级别的云服务将自己运行在容器上,并且将是证明规则的异常。此外,软件许可模型用于高价值、商业、现场的软件,将不得不接受容器采用的传播。软件的定价模型必须支持"打开"和"关闭"许可,因为容器被实例化、放大和缩小。9. 软件和系统可以自我修复、自我调节和自我管理开发人员和生产操作团队正在从日志、web /应用程序/数据库性能监视和用户体验监视和配置中淹没数据。此外,这些不同类型的数据都是竖向的,所以您必须将许多人带入一个房间来调试问题。然后就是知识转移的问题:开发人员花了大量的时间来讲述他们的应用程序的输入和输出、设置的阈值、用于监视事务的服务器拓扑,等等。通过聚合大量的数据到一个存储库(在日志、性能指标、用户体验,和配置,例如),并应用大量的计算能力,机器学习,和专用算法,基于云计算的系统管理服务将大大缓解性能/日志/配置监视。这些云服务将通过观察事务来建立基线,通过观察事务(从必须管理阈值来节省ops团队),并了解与事务自动关联的服务器拓扑。使用针对这些基线的异常检测,系统管理服务将自动能够告诉开发人员,当事情偏离正常的行为时,并能够显示特定事务的问题的根源。开发人员需要考虑如何在编写应用程序时利用这种自动化,以便能够在云中这些智能管理系统之上创建自管理应用程序。10. 高度自动化的安全性和遵从性努力成为开发人员的新同盟尽管开发人员通常认为安全性和遵从性是"其他人的工作"或"交付代码的瓶颈",但基于机器学习和交付的综合安全性和遵从性机制的出现,将有助于使这些努力与快速的开发步调一致。具体地说,高度自动化的网络防御将被部署到"上游",以识别和纠正开发和"下游"的潜在安全风险,从而自动调整公司的安全配置文件,以适应正在进行的应用程序和环境变化(识别攻击、修复漏洞和评估持续的遵从性)。在某些情况下,这种保护是必要的,持续的合规评估是GDPR和类似任务的标志。开发人员、安全专业人员和最终用户都将受益于在devops生命周期中更加严格的、自动化的安全方法。

  • 软件开发和测试的 30 个最佳实践

    编译:伯乐在线/maifans这些软件开发和测试的最佳实践,可以帮你节省时间和避免问题。加入一个企业文化和编程实践已经定型的新公司,可能会是一种令人沮丧的经历。当我加入 Ansible 团队后,我决定整理我多年以来所学并为之奋斗的软件工程实践和准则。这是一个不明确的也不够详尽的准则列表,使用它们时需要智慧和灵活性。我对测试充满热情,因为我相信良好的测试实践既能确保满足最低质量标准(可悲的是许多软件产品做不到),并能指导和塑造开发本身。本文提到的这些准则,很多是与测试实践和理念相关的。其中一些准则针对 Python 的,但大多数不是。(对于 Python 开发者,PEP 8 应该是编程风格和指南的首先。)开发和测试的最佳实践1. YAGNI 原则:“You Aint Gonna Need It”。不要写你认为将来可能需要但现在不需要的代码。这是为假想的未来用例编码,这些代码将不可避免地变成死代码,或需要重写,因为未来结果总是与想象的稍有不同。如果你写代码用于将来的用例,我将在代码评审中对其质疑。(你可能而且必须设计 API,并确保未来的用例可用,但这是不同的问题。)这条原则也适用于被注释掉的代码;如果一个被注释掉代码块即将进入一个发布版本,那么它就不应该存在。如果代码可能要还原,请为代码删除创建一个问题单并引用提交对象的哈希字符串。YAGNI 原则是敏捷编程的核心要素,这个话题最好的参考书是 Kent Beck 写的《解析极限编程》(《Extreme Programming Explained》)。2 . 测试不需要测试。用于测试需要的基础设施、框架和库需要测试。除非你真的需要不要测试浏览器或外部库。测试你写的代码,而不是别人的代码。3.当第三次编写相同的代码时,也是将其提取成通用的辅助函数(并为其编写测试)的正确时机。测试中的辅助函数不需要测试;但当你将它们剔除出去然后再重用它们时,它们需要测试。到你第三次编写类似代码的时候,你通常会清楚地认识到你正在解决的通用问题的模型是什么。4. 现在来谈谈 API 设计(面向外部的对象API):把简单的事情做简单了,复杂的事情自然成为可能。首先设计简单的用例,如果有可能最好是零配置或参数化。为更复杂和灵活的用例(如需要)增加选项或额外的 API 方法。5. 快速失败。检查输入,如果遇到无意义输入或非法状态则尽早失败,最好是通过异常或错误响应使问题对调用者变得清晰。允许你的代码处理“有创意”的用例(例如,除非真的需要,否则在做输入验证的时候不要做类型检查)。6.单元测试测的是行为单元,而不是实现单元。我们的目标是在改动实现的情况下不改动行为,也不必更新测试,尽管这个目标不总是能实现。因此在可能的情况下将测试对象视为黑盒,通过公共 API 测试,而不调用私有方法或玩弄状态位。在一些复杂的情况可能做不到,如在特定的复杂状态下测试行为,以找到一个偶发的错误。这一点对于写测试非常有帮助,因为它迫使你在写测试代码之前思考你代码的行为以及你将如何测试它。测试首先鼓励更小,更模块化的代码单元,这通常意味着好代码。关于“测试优先”方法有一本很好的入门参考书,就是 Kent Beck 写的《测试驱动开发》(《Test Driven Development by Example》)7. 对于单元测试(包括测试基础设施测试),所有代码路径都应该被测到。100% 覆盖是一个好的开始。你不能覆盖所有可能状态的排列/组合(组合性爆炸),因此这个问题需要考虑。只有当有很好理由的情况下才允许有代码路径未经测试。没有时间不是一个好理由,最终会花费更多的时间。可能的好理由包括:真正的不可测(以任何有意义的方式),现实中不可能发生,或被其它测试覆盖。没有测试的代码是一种债。测量覆盖率和拒绝减少覆盖率 PR(拉取请求) 是确保你在正确的方向演进的一种方式。8. 代码是敌人:它可能出错,并且需要维护。少写代码,删除代码,不要写你不需要的代码。9. 随着时间的推移,代码注释不可避免地成为谎言。在现实中,很少有人在事情变化的时候更新注释。通过良好的命名法和已知的编程风格,努力使你的代码可读和自文档化。对于那些晦涩的代码,一定要写注释,例如偶发错误或意外情况的变通方案,或者必要的优化。解释代码的意图和及其原因,而不是解释代码在做什么。(顺便说一句,有些观点认为注释变谎言是有争议的。我仍然认为这是正确的,《程序设计实践》(《The Practice of Programming》)的作者 Kernighan 和 Pike 同意我的观点。)10. 防守思维。总是考虑什么会出错,无效的输入会引发什么,什么可能会失败,这将有助于你在许多错误发生之前发现他们。11.无状态和无副作用的单元测试,其逻辑应简单。将逻辑分解成单独的函数,而不是将逻辑混合到有状态和充满副作用代码中。将有状态代码和有副作用代码,分为较小的更容易模拟的函数和无副作用地单元测试。(测试的开销越小意味着更快的测试)副作用确实需要测试,但是测试一次然后处处模拟它们通常是一个好的模式。12. 全局变量不好。函数优于类型。对象可能比复杂的数据结构更好。13.使用 Python 内置类型及其方法将比自己编写的类型运行快(除非你用C语言编写)。如果性能是一个考虑因素,请尝试弄懂如何使用标准的内置类型,而不是自定义对象。14. 依赖注入是一个实用的编程模式,明确你的依赖是什么和它们来自哪里。(对象,方法等以参数的形式接收它们的依赖,而不是实例化新对象本身。)这确实让 API 签名更复杂,所以这里需要权衡。如果一个方法最后为所有的依赖设置了10个参数,那这是一个不错的信号,不管为什么你的代码做得太多。关于依赖注入的权威文章是 Martin Fowler 的《控制反转容器&依赖注入模式》(《Inversion of Control Containers and the Dependency Injection Pattern》)。15. 需要模拟测试的代码越多,你的代码就越糟糕。为了测试一个特定的行为,需要实例化和牵扯的代码越多,代码越糟糕。我们的目标是小型可测试的单元,以及更高级别的集成和功能测试,以测试各单元是否配合正确。16. 面向外部的 API 是“预先设计”——同时要考虑未来的用例——真正重要的地方。改变 API 对我们和用户来说是一种痛苦,造成向后不兼容是可怕的(尽管有时无法避免的)。设计面向外部的 API 要细心,仍然要坚持“把简单的事情做简单”的原则。17.如果函数或方法超过 30 行代码,考虑分解它。一个良好的模块最大约 500 行。测试文件往往比这个要大。18 .不要在对象构造函数中工作,这里很难测试而且经常发生意外。不要在__init__ .py中添加代码(导入命名空间除外)。__init__ .py不是程序员通常期望找代码的地方,所以它是个“惊喜”。19. DRY(不要重复自己)在测试中没有在生产代码中要紧。单个测试文件的可读性比可维护性更重要(跳出模块复用的限制)。这是因为测试是单独被执行和阅读的,而且它们自己不是大系统的一部分。虽然在很多重复的时候创建可重用的组件更方便,但相较于产品代码,测试代码较少考虑。20.每当你看到有需要有机会就重构。编程是关于抽象的,你的抽象映射越接近问题域,代码就越容易理解和维护。随着系统的有机增长,需要改变结构以扩大它们的用例。系统越来越多的抽象和结构,如果不改变它们就成为技术性的债务。它会是更加痛苦的工作(更慢,越来越多的错误)。在特性开发估计中请考虑清除技术债务(重构)的成本。你遗留债务的时间越长,积累的利息就越高。关于重构和和测试的一本很棒的书是 Michael Feathers 的《修改代码的艺术》(《Working Effectively with Legacy Code》)。21. 代码正确为第一位,速度快第二位。在处理性能问题时,在修复错误之前先要做性能剖析。通常瓶颈不是你认为的那样。如果写晦涩的代码的唯一价值就是更快而且你已经做过性能剖析并证明了,那么它实际就是值得的。编写测试定期检测你要做性能剖析的代码,这样可以很容易让你知道你什么时候测试过。测试可以留在测试套件中,以防止性能退化。(通常情况下,添加定时代码总会改变代码的性能特性,使性能工作成为令人沮丧的任务之一。)22. 当更小、范围有限的单元测试失败的时候,可以给出更多有价值的信息,告诉你具体是什么错误。如果一个测试牵涉了半个系统来测试行为,那么它需要更多的调查以确定什么是错误的。一般来说,运行超过 0.1 秒的测试不是单元测试。没有所谓的慢单元测试。用限定范围的单元测试测试行为,你的测试行为扮演了事实上的代码规范。理想情况下如果有人想了解你的代码,他们应该能够把测试套件转换为行为的“文档”。Gary Bernhardt 的《快测,慢测》(《Fast Test, Slow Test》)是关于单元测试实践的一篇很棒的演讲。23. ”非我所创“不像人们说的那么坏。如果代码是我们写的,那么我们知道它是什么,我们知道如何维护它,在我们可以在适当的时候自由地扩展和修改它。这遵循了 YAGNI 原则:我们用那些适合我们需要用例的特定代码,而不用我们不需要的可以做复杂事情的通用代码。另一方面,代码是敌人,拥有必要的代码比拥有更多的代码更好。引入新的依赖关系时要权衡。24. 共享代码所有权是我们目标;沉默的知识不是好知识。这意味着最低限度要讨论或记录设计决策和重要的实施决策。代码评审(Code Review)是开始讨论设计决策的最坏时刻,因为在代码编写后,很难彻底更改。(当然在评审时指出并修改设计错误比没有好。)25. 生成器很棒!它们通常比迭代或重复执行的状态对象更短更容易理解。David Beazley的《系统程序员的生成器诀窍》(《Generator Tricks for Systems Programmers》)是关于生成器一个很好的介绍。26.让我们成为工程师!让我们考虑设计、构建健壮并实现良好的系统,而不是做膨胀的有机怪物。然而编程是一种平衡。我们并不总是建造火箭。过度设计(洋葱架构)同设计不完善的代码一样,处理起来非常痛苦。Robert Martin 的作品几乎都值得一读,《架构之洁:一个工匠的软件结构和设计指南》(《Clean Architecture: A Craftsman’s Guide to Software Structure and Design》)是这个话题一个很好的资源。《设计模式》(《Design Patterns》)是每一位工程师都应该阅读的经典编程书。27. 间歇失败的测试会侵蚀测试套件的价值,以至于最终每个人都忽略测试运行结果,因为总有一些失败的事情。修复或删除间歇性失败测试是痛苦的,但这些努力是值得的。28. 一般来说,特别是在测试中,在需要等待一个特定的变化时候不要采用休眠随机时间的方式。Voodoo(Python 库) 的 sleeps 很难理解而且使你的测试套件变慢。29. 至少让你的测试失败一次。故意加入一个错误,并确保它失败,或在测试的行为不完整的情况下运行测试。否则你不知道你真的在测试什么。瞎写的测试实际上不能测试任何东西或它很可能永远不会失败。30. 最后一点:只关注特性改进是开发软件的一种可怕方式。如果开发者的工作不能确保最好的结果,那么不要让他们为自己的工作感到自豪。不处理技术债务会使开发变慢并最终导致产品更糟,问题更多。感谢 Ansible 团队,尤其是 Wayne Witzel,为改善这个列表中的准则而提出的意见和建议。

  • 印度首款处理器将得到软件支持,印度理工学院开发

    IT之家7月2日消息 根据外媒的报道,印度理工学院(IIT)为其开源Shakti处理器发布了软件开发工具包(SDK)。Shakti基于开源RISC-V指令集架构,由印度电子和信息技术部资助。该研究所承诺,开发板也将很快发布。IIT Madras的RISE集团于2016年开始致力于Shakti项目,计划发布一系列六类处理器,每个处理器服务于不同的市场。该集团表示,其处理器在面积,性能和功耗方面将与商业产品竞争。外媒表示,现在,印度像中国和欧盟一样,对设计自己的处理器感兴趣,不想依靠美国制造商设计的处理器。

  • 短视频app软件开发的流程,10分钟的一点通

    “我有一个很好的创意,但我不懂技术,我想做一款类似抖音的短视频软件,我应该怎么做?”这可能是一些以前没有接触过软件开发工作的朋友想要问的问题,本篇文章就来针对此问题讲解一下,非行业内人士该如何完成短视频app软件开发,实现上架运营呢?一、 寻找开发人员首先,软件运营方,也就是很有想法的那位朋友,要与软件开发人员(通常是与软件开发公司)进行短视频app软件开发相关的需求对接,对接的内容包括而不限于软件功能、功能的机制、软件的工期和报价。在开发方与运营方协调完这些事以后,双方就可以签订合同了。运营方的需求会被送到产品经理那里,产品组人员对软件进行设计,期间要进行商讨洽谈,最终定下产品方案来。二、 对接三方在软件开发方对短视频app软件进行产品设计时,运营方也并非无所事事,一款短视频app软件的定制开发,需要有多个三方进行协助,比如运营软件所需的服务器、比如与向腾讯开放平台和微信开放平台申请,QQ微信登录分享的权限。比如接入短信API……在此期间,软件开发方会有专人陪同,从旁进行协助工作。三、 开发调试在用户与全部三方对接完毕后,短视频app软件开发工作也告一段落,软件开发方的测试组人员会对软件进行一系列的调试,以确保它们的兼容性没有问题,运行的时候能够顺利的跑通。在确定这些后,软件开发方会将软件系统搭建在服务器上并交付给客户,客户开始试运营,在试运营过程中,有时会发现一些系统的bug,这时候,运营方只需要把软件BUG反馈给软件开发方,开发方调试解决后,即可把软件正式投入上架运营了。短视频app软件开发、调试软件开发完以后,该上架的上架,不想上架的也可以从其他渠道分发,就此,短视频app定制开发工作告一段落。直到现有功能不再满足用户需求……更多与短视频app软件开发、定制相关的行业资讯和分析会在以后逐渐放出,敬请期待,需要的朋友请关注我。

  • 曝马斯克不满特斯拉自动驾驶开发 10%软件开发人员离职

    据多位知情人士透露,过去几个月,特斯拉自动驾驶软件团队中至少有11名成员离职,占整个团队的近10%,其中包括一些资深成员。剩下的几名经理现在正与马斯克直接合作。今年5月,据Electrek援引知情人士曾透露,特斯拉重组了其自动驾驶软件团队,并由马斯克亲自掌管。当时,马斯克解除了特斯拉自动驾驶团队Autopilot软件副总裁斯图尔特·鲍尔斯(Stuart Bowers)的职务。鲍尔斯手下的部分高管同时被解雇,而有些人则得到提拔。6月份,据CNBC报道,特斯拉自动驾驶团队负责人泽尔科•波波维奇(Zeljko Popovic)将离职,加入位于旧金山的自动货运初创企业Embark。波波维奇负责为特斯拉开发高精度的美国高速公路地图,并创建了一个“传感器融合系统”,将特斯拉汽车使用的许多摄像头、雷达和超声波传感器的数据结合起来。传感器融合系统使自动驾驶仪能够“看到”路上的其他车辆。总的来说,特斯拉以高离职率闻名,在其自动驾驶团队更是如此。在过去几年里,这个团队换了好几位高管。2016年,Autopilot项目总监斯特林·安德森(Sterling Anderson)离职,并在自动驾驶领域创立了自己的初创公司。随后,曾帮助开发苹果编程语言的克里斯·拉特纳(Chris Lattner)接任,但他在特斯拉只工作了大约6个月即离职。去年,特斯拉最终聘请Snap的斯图尔特·鲍尔斯担任自动驾驶软件业务副总裁。在此期间,由于特斯拉给辅助驾驶功能设置越来越紧迫的计划,希望借此实现全自动驾驶系统,导致很多高管离职。在今年4月份举办的“自动驾驶日”上,马斯克承认,特斯拉的一些自动驾驶功能仍需要改进。但同时,他夸下大口称,到明年年底,特斯拉电动汽车将具备“自动驾驶出租车”的功能——也就是说,它们将在正常情况下完全自动驾驶,不需要人工干预。马斯克表示,到2020年,将有100万辆特斯拉汽车在道路上进行“自动驾驶出租车”(robotaxi)业务。然而,业内人士认为,这只是马斯克在“吹牛画饼”,目的是提振低迷的股价。在实际中,特斯拉的自动驾驶系统屡屡被曝出撞车等事故,显然还不够可靠。正如媒体所报道的,马斯克似乎正在“开除”那些不认同其为自动驾驶上路所设定的时间表的员工。这是一个非常激进的时间表,整个行业都对此表示怀疑。不过,这种质疑并没有阻碍马斯克的言论。他最近还一直在谈论特斯拉网络(Tesla Network),这是特斯拉“总体计划”(Master Plan)的一部分。该计划将使拥有完全自动驾驶硬件的特斯拉汽车能够像机器人(16.080, -0.11, -0.68%)出租车一样运行,为车主和特斯拉自身创造收入。马斯克表示,消费者在现在购买的特斯拉汽车将是一种“增值资产”,因为它有可能被用来在未来创造收入。马斯克还称,一旦机器人出租车成为可能,特斯拉很可能会停止向消费者出售汽车,至少不会以与现在相同的价格出售汽车。但这依赖于一些假设。第一,首先特斯拉将能够制造出一款能够在任何时候都能完全自动驾驶的汽车,而且车内没有人类司机;第二,自动驾驶汽车比人工驾驶的汽车更安全、更便宜;第三,这些机器人出租车将能够自己开车赚到足够的钱。

  • 想做一名优秀的软件开发经理?看看你是否具备这5个特征

    软件开发经理的工作不是提供一件产品或某项功能,也不是实现任何指标或增加收入。经理的主要工作是确保他所带领的工程师在他们的职业生涯中成长,学习并提高专业知识。经理工作的第二部分内容是确保团队在这个成长的过程中感到快乐,让他们在面对工作时,尽可能地斗志昂扬。只要经理在所有这些工作的背后都有良好的规划并按主次顺序安排,那么功能、产品、指标和收入应该自然而然就会出现。如果想要深入了解一位优秀的经理应该掌握的最重要的领域,可以看看下面几点:· 以灵感为主导每个组织都需要一个起指引作用的北极星和一个宏伟的愿景。这有助于工程师从业务角度关注重要事项。经理应该帮助团队确定一个大胆的方向,而不是强制实行。任何级别或有任何资历的工程师都应有权提出会推动团队进步的想法,这意味着管理者应该随时随地准备倾听。因为如果工程师的想法被忽略了,他们就会停止分享这些想法,最终可能脱离这个集体。确保团队内部的每个人都有发言权是保证公司良好运转的必要条件。· 服务而不是命令许多人特别是学生,甚至是初级工程师,常常会认为经理就应该发号施令。但是,经理更应该做的是提供正确的成长机会和挑战,以及宏伟的愿景和指导来支持他们的团队。经理应该专注于为员工服务,而不仅仅是下达命令。经理应该提供保障措施,使工程师能够尽其所能,同时在他们偏离正轨时,帮他们恢复精力并从中学习经验。如果经理倡导的是下级恐惧上级的企业文化,那么最终他们所带领的只会是充满恐惧和怨恨的工程师团队。引起轻微恐惧的一种常见方式是盲目关注指标,让工程师对这个指标负责,而忽视了实际的客户价值和员工健康状况。在这种氛围之下,工程师最终只会担心是不是会做出可能导致指标下降的决策。而独立决策的能力是一名高级工程师的核心能力之一,但当工程师觉得他们的所做的决策可能成为限制他们职业发展的一个十分冒险的因素时,他们就不会想去做独立的决策了。经理应该营造一个能让工程师有安全感的环境,让他们感受到,他们的成功会得到庆祝,而失败则是一次成长的机会。· 谦虚和透明对于失去整个团队对经理的信任而言,没有什么能比隐藏议程或滥用权利行事更有效了。当一位经理不信任工程师时,他的团队一定会注意到,毕竟行动胜于雄辩!工程师和经理之间建立相互信任的关系对于整个团队的实力和长期发展至关重要。因为问题总是会出现,而错误也总是存在的!真正起作用的是团队会如何处理这些问题。如果工程师和经理之间的关系很紧密,这意味着经理可以更早发现问题,因为他的团队知道,在发生问题时就将其暴露出来,有助于想出一个好的解决方案。优秀的经理会以身作则,立即承认问题并承担责任,不会责怪他人,也不会在没有提出建设性解决方案或前进道路的情况下谈论问题。· 信任、核实、从不微观管理在工程师身上采用微观管理无疑是最耗费经理本人精力的方法之一了。这种管理模式会逐步地打破工程师们对经理的信任,因为这会让工程师觉得经理对他们不信任或认为他们能力不足。即使员工在努力实现预期目标时,微观管理也并不会是解决问题的良好方式。当经理对工程师的每一个举动都提出质疑时,上述提到的信任关系就会受到挑战。当然,信任不一定是盲目的,但检查项目的状态并不意味着要对工程师们实行微观管理。若能在不让他们满盘皆输的条件下为工程师提供一定的自我改进的空间,经理才更有可能看到他的团队能从这些经验中获得一些有价值的见解,而这些见解能够持续改进工程师们的工作能力。· 人比产品重要一件产品的失败就意味着参与其中的的团队浪费了时间?绝对不是!成千上万的人在开发一项产品时提升了自己的职位,成为高级工程师。这种成长经历不能因为他们创造的产品不复存在而被忽视。产品迭代出现,有些产品在多年后仍然很重要,但许多其他产品则被遗忘。然而,专业人才的培养从来都是至关重要是的。管理者应该倡导一种以人为本的企业文化。· 结论一个不合格的经理可能会带来灾难性的后果,特别是在工程师的成长直接与经理的行为挂钩的公司中。如果可能,寻找一位明确在乎员工职业发展,以帮助他们的团队成长为荣的经理。这样的话,成功的职业生涯将与你不期而遇!

  • 影响游戏直播软件开发的重要因素

    艾瑞咨询发布的《2019年中国游戏直播行业研究报告》指出,2018年中国游戏直播市场规模达到139亿元,市场规模稳步增长,行业走向正轨,游戏直播同时也成为了直播行业最具发展潜力的领域。在这样的市场环境下,为什么很多新入局直播行业的人,依旧选择传统的秀场直播软件开发,而不是游戏直播软件开发呢?图片来源:艾瑞咨询主播收益模式单一道具礼物打赏是游戏主播的主要收益模式,但也仅限于很多头部主播。对于平台运营方而言,礼物打赏收益毕竟有限,所获得的利润分成难以支撑整个平台的运营。同时,主播依托高人气引流,为自己带来额外的电商收益,平台方无法参与分成。高额的流量主播开支游戏直播平台是整个直播行业“挖角”现象最严重的领域。头部游戏主播身价过高,极易引起平台运营方的入不敷出,主播“跳槽”给平台带来的流量损失巨大。过高的风险及巨额的主播开支,让很多运营方望而却步。图片来源:艾瑞咨询游戏直播的商业化运作广告合作、自制游戏赛事、官方赛事主办,这些电竞游戏产业的商业化运作内容是游戏直播平台的灵魂。在没有充足的资金条件下,很难参与到游戏直播领域的激烈竞争中。恰恰是这些商业活动,能够短时间内给平台带来巨大的用户流量。用户交互高打赏率低游戏直播虽然受到当下很多年轻人的喜爱,但是根据艾瑞咨询发布的调研数据显示,接近70%的用户通过关注主播、评论等方式进行互动。其中仅有17%的用户有过付费打赏行为。单一的打赏模式,超低的付费打赏率,给游戏直播软件的运营带来巨大难题。图片来源:艾瑞咨询短视频深耕游戏业务短视频来势汹汹,很多头部短视频平台也开始慢慢向直播领域渗透。那么游戏直播肯定也成为了短视频平台关注的重点。艾瑞咨询表示,目前游戏直播平台主要以满足核心电竞人群的观看需求,基于地区化的特色游戏直播内容与轻度电竞内容这些细分领域上仍存在市场空缺。技术难度大开发成本高前面几点因素主要显示了游戏直播平台运营上的痛点,在游戏直播软件开发技术层面上,种类繁多的游戏内容,增加了开发成本。同时还需要满足边游戏边直播这样苛刻的条件,对于录屏技术要求较高,需要额外开发录屏工具软件,导致最终游戏直播软件开发保持在较高的开发成本。图片来源:艾瑞数据以上这些因素制约了当下游戏直播软件开发市场,使得游戏直播成为很多头部平台的主打内容,一般的平台运营方很难加入到“角逐”中。而传统的秀场直播软件开发,基于当下较低的开发技术门槛,多元化的收益变现方式,依旧受到新入局者的欢迎。文章原创,转载请注明转自“云豹直播系统”百家号数据资料来源:艾瑞咨询《2019年中国游戏直播行业研究报告》

  • 移动应用软件开发方向的大学生如何规划大学期间的学习计划

    首先,对于学习计算机软件开发的同学来说,在大一和大二期间应该打下一个扎实的基础学科基础,比如数学基础就比较重要,因为软件开发问题说到底就是个数学问题。另外,数学基础比较好对于未来的岗位升级或者是考研进修都具有较为实际的意义。如果在大一和大二期间要学习编程语言,应该结合自己的专业特点进行选择,毕竟编程语言与应用场景有密切的关联,对于移动应用方向的同学来说,Java就是不错的选择,一方面Java可以进行Android应用的开发,另一方面Java也可以用于后端服务的开发。另外,Java语言目前在整个IT领域依然有广泛的应用,而且由于Java语言自身具有健全的语言生态和较强的扩展性,未来Java语言依然有广阔的应用场景,作为软件开发的专业人员来说,掌握Java语言会给开发工作带来较多的便利。至于选择前端开发还是后端开发,应该根据自身的知识结构和能力特点进行选择,但是在当前大数据和云计算技术的推动下,前后端开发的传统边界正在逐渐模糊,前端开发后端化和后端开发前端化目前都是比较明显的趋势。简单的说,未来开发人员需要更全面的知识结构才能应对各种开发场景的变化。最后,学习软件开发一定要重视计算机基础知识结构,其中操作系统体系结构、数据结构、算法设计等内容一定要重点掌握,这些知识的掌握情况能够在很大程度上决定技术人员未来的工作能力和学习能力。我从事互联网行业多年,目前也在带计算机专业的研究生,主要的研究方向集中在大数据和人工智能领域,我会陆续写一些关于互联网技术方面的文章,感兴趣的朋友可以关注我,相信一定会有所收获。

  • 凌志软件前五大客户均为日企 8成收入来自对日软件开发服务

    ●长江商报记者郑玮7月17日,苏州工业园区凌志软件股份有限公司(下称“凌志软件”)回复了科创板第三轮问询。第三轮问询中,上交所共对凌志软件提了5个问题,分别关于收入确认、公司投资、收入相关财务信息披露、外协以及其他问题。其中,被关注的最多的当属收入相关财务信息披露。长江商报记者发现凌志软件客户集中度高,2018年前五大客户均来自日本。当年凌志软件对日软件开发服务收入高达3.9亿元,占比82.63%,而2016年该比例也达到了88.15%。凌志软件“三类股东”数量也较多。招股说明书显示,截至2019年3月31日,除公司员工持股计划外,凌志软件共有23家“三类股东”。上交所要求凌志软件说明现有“三类股东”是否符合资管产品杠杆、分级和嵌套的要求,过渡期安排是否已有明确时间进度安排等。从新三板到科创板公开资料显示,凌志软件成立于2003年1月,注册资本为3.6亿元,法定代表人为张宝泉,主营业务为对日软件外包服务和为国内证券业提供金融软件解决方案。招股书显示,2014年7月,凌志软件在新三板挂牌;2016年6月,公司向证监会提交首次公开发行并在A股上市的申请材料,2016年7月1日起,公司股票在新三板暂停交易;2018年11月,公司董事会审议通过了《关于撤回公司首次公开发行股票并上市申请文件的议案》,并于2018年12月收到《中国证监会行政许可申请终止审查通知书》,公司股票自2018年12月12日起恢复转让。目前,凌志软件仍在新三板挂牌,因重大事项已于4月11日开市起停牌。有业内人士表示,上一次撤回IPO申请主要因“三类股东”问题。“三类股东”即契约型私募基金、资产管理计划、信托计划。“三类股东”问题此前困扰了众多新三板拟IPO公司,清理“三类股东”、对“三类股东”穿透式核查等方式,成为一些拟IPO公司未能成功过会的主要原因。不过,“三类股东”问题迎来政策松动的迹象。近日全国股转公司推进的存量改革中,对特定事项协议转让规则进行了修订,股转公司为“三类股东”在IPO审核停牌期间的退出提供了实现通道,允许其通过特定事项协议转让业务完成股份的转让过户。重新回到IPO征程,凌志软件的底气或许也来源于不错的2018年财务报表。根据3月12日公布的2018年年度报告显示,凌志软件当年营业收入为4.67亿元,同比增长22.01%,扣非净利润为8931万元,同比增长55.69%。前五大客户均为日企让凌志科技受到关注的是,凌志软件的前五大客户与供应商均为日本企业,包括株式会社野村综合研究所、TIS株式会社、富士通株式会社、株式会社SRA、大东建托株式会社,年度销售占比分别为44.42%、9.31%、7.56%、6.96%、4.60%。凌志软件也表示,对日软件开发服务是公司的核心业务,主要包括公司为日本一级软件接包商或最终客户提供软件开发服务,还包括部分为日本一级软件接包商在中国设立的子公司提供软件开发服务,这两块业务收入均来自于日本市场。2016年、2017年和2018年对日软件开发服务收入占公司营业收入的比例分别为88.15%.82.38%和82.63%,占比较高。未来对日软件开发服务仍将是公司重点发展的业务,因此公司存在依赖日本市场的风险。招股书显示,公司最大客户野村综研软件发包金额占其生产成本的44.6%,对中国企业的发包金额从2004年的64.59亿日元增加至2017年的195.32亿日元,年复合增长率为8.88%。总体来看,日本企业在中国市场加大了服务项目的发放,侧面反映中国IT行业劳动成本具有明显的优势。同时,招股书也表示,如果野村综研经营情况发生重大不利变化或者发生野村综研和凌志软件终止合作的情况,将直接影响到凌志软件的经营,给凌志软件经营业绩造成不利影响。值得关注的是,凌志软件国内软件开发业务的营收占比有所上升,凌志软件于2016年、2017年和2018年国内软件开发服务收入占公司营业收入的比例分别为11.85%、17.61%和17.37%。对此,有专业人士认为,国内客户的增加有助于降低公司对日本业务的依赖。

  • 特斯拉:不想造车的自动驾驶软件开发商不是好的发明家

    众所周知,特斯拉是目前最火的造车企业之一,而且该公司首席执行官埃隆马斯克还时不时登上Twitter账户,与众多特斯拉粉丝和吃瓜群众互动,经常透露公司目前的技术研发和产品研发状况。而除了其专业-电动汽车之外,特斯拉对自动驾驶的发展也贡献颇多。2018年,马斯克在接受媒体采访时曾表示,到2019年,特斯拉将超越其他任何汽车制造商,实现完全自动驾驶,而且对这一规划始终自信满满。但是到2019年3月份,特斯拉却突然变得保守,将官网的“完全自动驾驶”改成了“未来驾驶”,而且其自动驾驶系统Autopilot功能的页面描述也被大幅修改。虽然很多人都嘲笑特斯拉对其自动驾驶功能过于乐观,但是不可否认的是,从2018年至今,特斯拉公布的一系列自动驾驶专利或许能够早日让大家看到在公共道路上运营的完全自动驾驶汽车。现在我们可以来看看,“发明家”特斯拉都公布了哪些自动驾驶方面的技术专利?车辆精确定位技术2017年,特斯拉就曾对车辆定位技术提出专利申请,2018月12月,美国专利商标局正式公布了该项专利。特斯拉提出,带有定位接收器的智能手机一般只能够确定5米之内的物体,而且当定位接收器接近建筑物、桥梁、树木等物体时,定位的准确性会下降。虽然可能会受到导航卫星信号的影响,但为了提高自动驾驶汽车的安全性,精确的定位技术是必须的。特斯拉表示,可以让车载摄像头与检测位置互相匹配,并将车队中其他车辆作为“合作参考点”,共享原始全球卫星导航系统(GNSS)数据,并进行地位修正。此外,如果车辆间不共享数据,也可利用其他传感器修正GPS数据,从而在即使GPS信号没那么强的地方,特斯拉车辆也能够不受外界影响,获得更准确的定位数据。车辆自检专利除非定期对车辆进行全面检查,否则大多数汽车都是等到某样部件坏了才会去修。为了避免此种状况,特斯拉申请了车辆自检专利。特斯拉指出,现在检测车辆损坏的方法一般有两种:一是等到故障发生,替换或修复故障部件(非常危险,因为故障发生时可能会造成安全威胁);二是定期检查或更换设备(基于“经验”,频繁保养或检查可能会加快设备故障,且费时又费钱)。为解决上述问题,特斯拉申请专利时提出,可以在汽车发生故障之前,让车辆自行检测,甚至车辆可自动驾驶至服务中心。该专利提出检测汽车某些部件“应力周期”的方法,可在车辆潜在故障出现之前就检查出来,而且处理器可将应力周期数据和故障数据发送至服务中心,让服务中心确认后,汽车可自行驾驶至服务中心进行维修。Autopilot优先响应紧急信息在自动驾驶汽车等待计算机处理信息时,可能有些关键信息会被卡住,从而导致非关键信息先出现的情况,可能会让车辆和乘员陷入险境。为避免此种情况,特斯拉申请了一种能够将车辆传感器的紧急信息快速输入其自动驾驶软件Autopilot中的方法,从而提升Autopilot在紧急情况下的反应能力,降低事故发生的可能性。特斯拉在专利中提出两种方法,第一种是,如果传感器探测到紧急信息,与其他信息相比,该信息会以更高的传输功率发送至主计算机,因为传输功率较低的信号会被认为是“背景噪音”;第二种方法是,对接收紧急信息的自动驾驶传感器进行编程,让其停止继续发送信号,在车辆主计算机接收到紧急信息之后,再指导传感器恢复通信。安全处理自动驾驶系统软件的错误特斯拉自动驾驶系统在运行时,会接收到大量实时输入的数据流。一方面用于训练系统的神经网络,另一方面用于激发车辆对正在处理的情况进行响应。如果此类数据中有些是错的或是处理延迟、处理不当,带来的实际影响将是灾难性的,可能就会导致交通事故、财产损失以及人员伤亡等。特斯拉提出方法避免此类处理不当的情况,以全面提高自动驾驶软件的安全性。特斯拉在专利中提出,如果某些错误导致自动驾驶车辆的神经网络进入挂起状态或超时状态,而且此种状态超过了预定时间,将采取措施进行安全处理。如果是出现超时错误,神经网络处理器会停止提供输出数据,或者停止对输入的数据做出响应。如果是程序错误或数据错误等其他类型的错误,神经网络处理器会继续提供输出数据,但是结果可能是不准确的时候,自动驾驶软件会忽略此类信息,继续像往常一样运行。汽车个性化系统车载摄像头作为自动驾驶系统的重要组成部分,除了能够探测安全驾驶周围环境,帮助自动驾驶汽车之外,还能够帮助提升乘员的乘坐体验。特斯拉为了提高自动驾驶功能,优化乘员体验,提出了一个全新专利。该专利是一个汽车个性化系统,包括一个图像捕获装置,能够获取车内乘员的位置和图像,估算乘员身体部位的高度,并根据身体部位高度,控制车载系统,还能够计算车内乘客数量。此外,特斯拉还希望该专利能够根据每个乘客的具体需求调整车内环境。如,根据预先设定的路线,调整按摩功能、环境光的颜色等。而且在感知到紧急情况后,可自动将汽车导航至车辆乘员偏好的医疗中心。公布专利是真“大方”?对于汽车制造商来说,专利技术是其能够立足市场的根本,而在这个人力与资金都非常密集的自动驾驶汽车行业,谁拥有最多、最有用的专利技术就是其能够领先行业其他玩家的根本,无怪乎纽约金融研究机构ARK Invest分析师James Wang表示,特斯拉自行研发的完全自动驾驶(FSD)计算机芯片已经使该公司比竞争对手的自动驾驶发展领先了4年。可能有人会觉得将专利技术公布的特斯拉未免过于“大方”了,但是公开专利其实是一举两得的行动。一方面,可以让其他竞争对手了解自己的进度,吸引更多人才的加入,创造一个良性的竞争环境;另一方面,就算有企业开始使用其专利,既可以让其专利得到反复测试,又可增加其专利的使用次数,从而渐渐形成行业标准,或许有朝一日能够让特斯拉成为自动驾驶行业标准的缔造者。来源: 盖世汽车网

  • 三十年软件开发之路:老码农的自我修养!

    【CSDN编者按】“千帆过尽仍少年”,对于程序员来说,保留技术初心、不断提升实力是夯实自己的不二法则。而本文的作者,作为一名有着三十多年开发经验的“老”程序员,就在本文中详细总结了自己这些年踩过的坑和实践得出的真理,谈到了包括软件开发、团队工作、个人成长等方方面面。相信阅读本文后,会帮助你成为更优秀的程序员。声明:本文已获作者 Julio Biason 翻译授权。作者 | Julio Biason译者 | 王艳妮,责编 | 郭芮以下为译文:这是我30年来从事软件开发过程中所学到的一些实际经验,可能有些听起来愤世嫉俗,但都是我的切身经验之谈。再次强调,有些内容真的是愤世嫉俗,有些则是对不同工作岗位的长期观察。软件开发先明确问题,再开始写代码如果你不知道你想要解决的问题是什么,那你肯定就不知道要写些什么代码。在编写任何代码之前,先明确地把应用程序是如何工作的写下来。“如果没有需求或设计,编程就是向空文本文件不断增加bug的艺术。”——Louis Srygley有时,即使只是“电梯演讲”(指短时间内表述结果内容)那么长——用仅仅两个自然段来描述这个应用程序的功能——也足够了。有时候我看着自己的代码发呆,不知道下一步该怎么做,其实往往是因为下一步本来就还没有被定义出来。一般出现这种情况,就意味着是时候停下来,与同事们讨论一下了——或者重新考虑解决方案。将步骤写为注释如果你不知道如何开始,请先用自然语言、英语或你的母语描述应用程序的流程,然后用代码填充注释之间的空白。比这更好的做法是:将每个注释视为一个函数,然后编写出能完全实现其功能的代码。Gherkin是帮助你了解期望(expectation)的好帮手Gherkin是一种测试描述格式,它指出“鉴于系统处于特定状态,当发生某些事情时,这是预期的后果”。即使你不使用任何能读取Gherkin的测试工具,它也会让你很好地理解应用程序的预期效果。单元测试很好,集成测试更好在我目前的工作中,我们只测试模块和类(例如,我们只为视图层编写测试,然后仅测试控制器层,依此类推)。它能让我们了解到某一部分有没有出错,但缺乏对整体的观察——而集成测试测试了整个系统的行为,在这方面会表现得更好。测试可以让API更好我们在不同层次中编码:有一个存储层,应该使我们的数据永久存储;有一个处理层,应该对存储的数据进行一些转换;有一个视图层,它有关于数据必须如何被展示出来的信息......等等。正如我所提到的,集成测试感觉更好,但是单独测试不同层可以让你更好地了解其API。然后你可以更好地了解如何调用东西:API是否太复杂了?是否需要保留大量数据才能进行一次调用?做你知道如何在命令行上运行的测试也不是说命令行对于任何项目都很重要,但是当你知道运行测试的命令时,你就知道如何让测试的执行自动化起来,然后你可以在一个连续的集成工具中使用这些测试。时刻准备好扔掉你的代码很多人在刚开始使用TDD(测试驱动开发,Test-Driven Development)时,一旦被告知他们可能不得不重写很多东西,就会变得很生气。TDD“旨在”扔掉代码:越了解你的问题,那么你就会越明白,无论你写了什么,从长远来看都无法解决问题。所以你不应该担心这个。你的代码不是一面墙:如果你必须永远抛弃它,那也不是白白浪费了材料。当然这意味着你编写代码的时间一去不复返了,但是你现在对这个问题有了更好的理解。好的语言生来带有综合测试可以肯定的是,如果一种语言在其标准库中自带一个测试框架——即使小得不能再小——那么与没有测试框架的语言相比,它周围的生态系统仍将拥有更好的测试,无论该语言的外部测试框架有多好。未来思路是垃圾思路当开发人员试图解决问题时,他们有时会试图找到一种方法来一下解决所有问题,包括未来可能出现的问题。但现实就是这样:未来的问题永远不会到来,你最终要么必须维护一堆永远不会被完全使用的庞大代码,要么得整个重新写,因为有一大堆屁用没有的东西......解决你现在遇到的问题,然后解决下一个,然后再下一个。直到有一天,你会发现这些解决方案中显现出了一种固定的模式,然后你才能真正地“一次性解决所有问题”。文档是写给未来自己的情书我们都知道,为函数、类(class)和模块编写该死的文档是一个痛苦的过程。但是以后当你看到文档就能回想起来当时你编写函数时的思路,你就会明白将来文档能在关键时刻救你一命。功能文档是份合同当你以编写文档作为自己编程工作的起始点时,你实际上是在签订合同(可能是跟未来的自己):我说了这个函数要做这件事情,那么它就必须做这件事情。如果稍后你发现代码与文档不匹配,那你就是代码出了问题,而不是文档出了问题。如果一个函数的描述包含“和”,这就是不对的一个函数应该且仅应该做一件事,真的。当你编写函数文档并发现你写了“和”这个字的时候,这意味着该函数不仅仅是做一件事。那么就需要将该函数分解为两个独立函数并删除“和”。不要使用布尔型变量作为参数当你设计一个函数时,你可能会想要添加一个flag——不要这样做。现在,让我给你举个栗子:假设你有一个消息传递系统,并且有一个函数可以将所有消息返回给用户,称为getUserMessages。但有一种情况是需要返回每条消息的摘要(例如,第一段)或完整消息,因此,你添加一个名为retrieveFullMessage的flag/布尔参数。再说一次,不要这样做。因为任何读你代码的人都会看到getUserMessage(userId,true)并想知道这里的true到底是个什么意思。你可以将函数重命名为getUserMessageSummaries并使用另一个getUserMessagesFull或类似的东西,但每个函数只调用原始的getUserMessage为true或false——但是类/模块外部的接口仍然是清晰的。但是一定“不要”在函数中添加flags / Boolean作为参数。注意界面的变化在上面几点中,我提到了重新命名函数的问题,如果你能控制使用该函数的整个源头,那就不算是问题,只需要搜索和替换即可。但是,如果该函数实际上是由库公开的,那么你不能随便地更改函数名称。这将打破你无法控制的许多其他应用程序,并惹恼其他人。你可以通过文档或某些代码功能创建新函数并将当前函数标记为已弃用,然后,经过几次释放后,你终于可以Kill掉原来的函数了。(你可以做的一个有些混蛋的举动是创建新函数,将当前函数标记为已弃用,并在函数开头添加一个休眠,这样一来使用旧函数的人会被迫更新。)好的语言自带集成的文档如果语言有自己的方式来记录函数、类、模块或其他,而且带有一个哪怕最简单的文档生成器,你就可以确切知道所有的函数、类、模块、库、框架都具有良好的文档了(不是说一定特别好,但至少是比较好的)。大多数情况下,没有集成文档的语言,文档方面做得都不怎么样。一门语言绝不仅仅是一门语言而已编程语言就是你写的、而且能做事情的东西,但在特殊关键词以外它还有很多别的东西:它有一个构建系统,它有一个依赖控制系统,它有一种使工具/库/框架互动的方式,它有一个社区,它有一种与人打交道的方式。不要仅仅因为一种语言容易使用就选择它。永远记住,你可能因为一种语言的语法很简明而支持这种语言,但是与此同时你也是在支持维护人员对待这个社区的方式。有时候,宁愿让应用程序崩溃也不要什么都不做虽然这听起来很奇怪,但即使在处理过程中添加了某些错误,也不要默默地捕捉到错误但什么都不做。Java中一个可悲的常见模式是:try { something_that_can_raise_exception()} catch (Exception ex) { System.out.println(ex);}这看起来跟处理异常没有什么关系——除了重复了一遍,仅此而已。如果你不知道如何处理它,那就随它去吧,你早晚会知道它会发生什么。如果你知道如何处理该问题,那么就处理它与前一点相反:如果你知道什么东西在何时会导致异常/错误/某种结果,并且知道如何处理它,那么就请处理它吧。显示错误信息,尝试将数据保存在其他位置,将日志文件中用户的输入捕获到以便以后处理,但要记得处理它。类型决定你的数据是个什么东西内存中只是一串字节序列;字节只是0到255之间的数字组合;这些数字的真正含义取决于语言的类型系统。例如,在C中,值为65的char型变量可能是字母“A”,值为65的int型变量是数字65——处理数据时请不要忘记这一点。这也是为什么大多数人在用布尔型变量做加法以查看True的数量时经常出错。现在,让我展示一下我最近看到的一个JavaScript里的例子:console.log(true+true === 2);> trueconsole.log(true === 1);> false如果你的数据具有模式(schema),请使用结构(structure)来保留它你可能会想要使用列表(或元组,如果你用的语言允许的话)来保存数据,如果它很简单——比如说,只有2个字段。但是如果你的数据有一个模式(schema),有一个固定的格式——你应该每次都使用一些结构来保存它,不管是用struct还是class。理解并保持cargo cult的方式“Cargo cult”是一种理念,如果其他人那样做了,那么我们也可以。大多数情况下,cargo cult只是对一个问题的偷懒的解决方法:“如果X这样做了,我们为什么要考虑如何正确存储我们的用户数据?”“如果有某巨头公司是这样存储数据的,那么我们也可以”。“如果有某巨头公司支持这种做法,那就说明这种方法很好。”......不要管所谓的“合适的生产力工具”,你只需要尽力去push进程“合适的生产力工具”其实意味着:对于某件事情,有一个正确的工具和一个错误的工具——例如,应该使用另外的某种语言/框架而不是当前的语言/框架。但每当我听到有人提到这个词时,他们都是在试图推销他们喜欢的语言/框架,而不是合适的语言/框架。“正确的工具”比你想象的更明显也许你当前的项目需要处理一些文本,也许你很想说“让我们用Perl吧!”,因为你知道Perl在处理文本时非常强大。但你漏掉了哪一点呢?你在一个C的团队工作,每个人会C,而不是Perl。当然,如果它是一个小的、“放在角落”的不起眼的项目,那么用Perl就可以了——但如果它对公司很重要,那么最好还是用C。PS:你的英雄项目(本文稍后将详细介绍)可能因此而失败。不要跟你项目之外的事情纠缠有时人们会试图改变外部库/框架,而不是使用适当的扩展工具——例如,直接对WordPress或Django进行更改。这样很容易让你的项目秒瘫痪,变得无法维护。一旦发布了新版本,你就必须与主项目保持同步,并且很快就会发现改动不再适用,你将把外部项目留在一个旧版本中,且充满了安全漏洞。数据流动比模式更重要(再次说明,这仅仅是个人意见)当你了解数据如何在代码中流动时,你的代码质量就会更上一层楼,这比无脑应用一堆设计设计模式(design pattern)好多了。设计模式是用来描述解决方案的,但它不能找到解决方案(同样,个人观点)大多数时候我看到设计模式被应用的时候,它们被用作寻找解决方案的一种方式,所以你最终会扭曲一个解决方案——有时候,甚至是扭曲问题本身——来适应某个设计模式。首先,解决你的问题,找到一个好的解决方案,然后你可以检查模式,以提供如何命名该解决方案的思路。我经常看到这种情况发生:我们有这个问题;一个设计模式接近正确的解决方案;让我们使用这个设计模式吧;现在我们需要在适当的解决方案基础上添加很多东西以适应这个设计模式......学习函数式编程的基础知识你不需要彻底搞懂“什么是一个单子(monad)?”和“这是一个函子(functor)?”等问题,但要知道不能一直改变数据——使用新值创建一个新元素(将数据视为不可变),并尽可能使函数/类不保留某些内部状态(纯函数/类)。认知成本是可读性的杀手“认知失调”是一种高大上的说法,但其实意思就是“我需要同时记住两个(或更多)不同的东西才能理解这一点。”把这些不同的东西保留在你的头脑中会产生成本,并且事物之间关联性越小,这种成本就越会不断积累(因为你必须把所有这些都记在脑子里)。例如,将布尔值相加以计算True的数量就是一种轻微的认知不协调;如果你正在阅读一段代码并看到一个sum()函数,你知道它是列表中所有数字的总和,你就预料到列表由数字组成,但我看到过人们使用sum函数计算布尔值列表中的True的数量,这也太特么容易让人糊涂了吧。Magical Number 7 ,正负二(7+-2的范围内)“magical number”是一篇心理学文章中提到的概念,意思指人们可以在同一时间记住的事物的数量。如果你有一个函数,它调用一个调用函数的函数,该函数又调用一个调用函数的函数……再往下说下去你可能要疯。想一想:我会得到这个函数的结果,然后将它传递给第二个函数,得到它的结果,然后传递给第三个函数。但是:当今,心理学家更多地谈论Magical Number 4,而不是7。把函数当成写作文(如“我将调用该函数,然后该函数,然后该函数......”),而不是函数作为主体(如“该函数将调用该函数,将调用该函数......”) 。走捷径挺nice的,但只是在短期内如此许多语言、库、框架都有缩短工作时间的方法,减少了需要你打字输入的内容。但是,稍后,这些东西会让你栽跟头,你将不得不弃用这些捷径并懂得人间正道是沧桑的道理。因此,在使用之前,先了解那些捷径是如何做事情的。你不需要先用难的方式写东西然后再用捷径的方式清理:你只需要走捷径在后台做事情,所以你至少知道使用它可能出错的地方在哪里,以及如何用非捷径方式替换它。抵制“轻松”的诱惑当然IDE会帮助你完成大量的自动填充并让你轻松构建你的项目,但是你明白发生了什么吗?你了解你的构建系统是如何工作的吗?如果你必须在没有IDE的情况下运行你的程序,你知道该怎么做吗?如果没有自动填充你能记住你的函数名吗?是不是有办法打破/重命名一些东西让它们更容易被理解?......要对窗帘后面的东西保持好奇。总是在你的日期中使用时区处理日期时请始终添加时区。你的计算机时区和生产服务器时区(或其中一个实例时区)将始终存在问题,你将花大量时间来调试为什么界面总是显示错误的时间。总是使用UTF-8在日期上出现的问题,也将出现在对字符的编码上。所以时刻记得将你的字符串转换为UTF8,将它们作为UTF8保存在数据库中,在你的API上返回UTF8。你可以转换为任何其他编码方式,但UTF8赢得了编码战争,因此更容易保持这种方式。从笨办法开始远离IDE的一种方法是“从笨办法开始”:只需获取编译器并获得一个带有代码突出显示的编辑器(任何编辑器),做你该做的事情:写代码,构建它,运行它。不,这并不容易。但是当你跳进某个IDE时,你看到某个按钮只会简单地想,“是的,它会运行它”(顺便说一下,这正是IDE所做的)。日志用于事件,而不是用户界面很长一段时间,我使用日志向用户显示正在发生的事情——因为,你知道的,使用单个东西会更容易一些。使用标准输出通知用户发生了什么事件,使用标准错误通知用户有关错误的信息,但使用日志来捕捉可以在日后轻松处理的东西。将日志想成是你必须解析以便在那时从中提取一些信息的东西,而不是用户界面,它不一定要是让人看得懂的明文。Debugger们被高估了我常常听到很多人抱怨,不能Debug的编辑器有多糟糕。但是当你的代码投入生产时,你无法运行你喜欢的Debugger;哎呀,你甚至不能运行自己喜欢的IDE;但是logging......logging随处都可以运行......你可能在崩溃时没有所需的信息(例如,不同的日志记录级别),但你可以启用日志记录以便稍后找出某些内容。不是说Debugger们很糟糕,只是它们没有大多数人想象的那么有用。始终使用版本控制系统“这只是个随便写的破程序,我只想学点东西”——这不是一个不使用版本控制系统的好借口。如果你从一开始就使用版本控制系统,那么当你做了一些傻事时,撤销会更容易。每次提交一个更改我见过人们编写提交消息,如“修复了问题#1,#2和#3”。除非所有这些问题都是重复的——那么其中两个应该已经不存在——它们应该分三次提交,而不是一次。尝试在每次提交中只进行一项更改(并且这里的更改并不是“一个文件更改”; 如果一个更改需要更改三个文件,你应该将这三个文件一起提交。想想“如果我还原这一步,那是什么消失了?“)当你过度交换时,“git add -p”是你的朋友(仅限Git的主题)Git允许使用“-p”部分合并文件,这允许你仅选择相关更改并不管其他更改——可能是为了新的一项提交。按数据/类型组织项目,而不是功能大多数项目的组织如下:.+-- IncomingModels| +-- DataTypeInterface| +-- DataType1| +-- DataType2| +-- DataType3+-- Filters| +-- FilterInterface| +-- FilterValidDataType2+-- Processors| +-- ProcessorInterface| +-- ConvertDataType1ToDto1| +-- ConvertDataType2ToDto2+-- OutgoingModels +-- DtoInterface +-- Dto1 +-- Dto2换句话说,它们使数据按功能分类组织(所有传入的模型都在同一目录/包中,所有过滤器都在同一个目录/包中,依此类推)。这很好,很有效。但是当你按照数据进行组织时,将项目拆分到较小的项目中会更容易——因为在某些时候,可能你想要做的与你现在正在做的几乎一样,只是有些许小的差异。.+-- Base| +-- IncomingModels| | +-- DataTypeInterface| +-- Filters| | +-- FilterInterface| +-- Processors| | +-- ProcessorInterface| +-- OutgoingModels| +-- DtoInterface+-- Data1| +-- IncomingModels| | +-- DataType1| +-- Processors| | +-- ConvertDataType1ToDto1| +-- OutgoingModels| +-- Dto1...现在,你可以创建一个仅处理Data1的模块,另一个仅适用于Data2的模块,依此类推,然后你就可以将它们分解为独立的模块了。然后当你有另一个项目也有Data1但也处理Data3时,你可以重新用上Data1模块中的大部分内容。创建库我已经见过很多项目要么创建一个包含不同项目的大型存储库,要么保留不同的分支,这些分支不被用作以后加入主要开发区域的临时环境,而作为一个小而不同的东西延续下去了(从上文讲到的模块化角度来说,请想象一下,我没有构建一个重用Data1类型的新项目,而是拥有一个具有完全不同的主函数和Data3类型的分支)。为什么不将公共部分拆分出来加到库里并在不同的项目中应用它呢?原因在于,大多数情况下,“因为人们要么是不知道如何创建库,要么是他们担心如何将这些库‘发布’到依赖源中而不致泄露(因此也许你也应该了解你的项目管理工具如何检索依赖项,以便你可以创建自己的依赖项存储库)。”学会监控从前,为了理解系统的行为方式,我添加了大量的指标:输入速度、输出速度、中间滞留数量、已处理的数量......这样可以很好地了解系统的行为方式:速度在下降吗?如果是的,那我可以检查正在输入系统的内容以了解原因。在某些时候下降是否正常?......事实上,在此之后,试图查明一个没有任何监控的系统有多健康就变得很奇怪,仅使用“是否应答请求”来检查系统运行状况不再适用。尽早添加监控将有助于你了解系统的行为方式。config文件是个好东西想象一下,你编写了一个函数,你必须为它传入一个初始值才能开始运行(例如,一个推特用户帐户ID)。但是后来你又必须用两个值来做,所以你就直接用另一个值再次调用了该函数。使用配置文件更有道理,只需使用两个不同的config文件运行应用程序两次。命令行选项很奇怪,但很有帮助如果你将某样东西移动到config文件,你还可以通过添加选项来选择配置文件并公开它来帮助用户。现在对每种语言的命令行选项都有一些库可以处理,这将有助于你构建一个良好的命令行,并为你的用户提供一个标准的接口。不仅仅是功能组成,还有应用程序组成Unix自带“应用程序只做一件事,并且把它做好”的理念。如今,我说你可以使用一个带有两个配置文件的应用程序,但是如果你需要两个应用程序的结果呢?那时你可以编写一个应用程序,用两个配置文件读取第一个的结果并转换为单个结果。即使是做APP,也要从原始的东西开始APP的开发可能会涉及微服务——这很好——但微服务需要一些关于应用程序如何通过线路(协议等)在彼此之间“对话”的想法。你不需要从那开始,应用程序都可以从文件中写入和读取,这样容易多了。当你了解了网络是如何工作后,再通过电话进行交谈时可能会担心的吧。优化是面向编译器的假设你需要更高的性能,你可能很想看看你的代码和“可以在这里挤出更多性能的东西”或“如何在这里删除几个循环来获得更多速度”。好吧,猜猜怎么着?编译器知道如何做到这一点。智能化的编译器甚至可以删除你的部分代码,因为它始终会生成相同的结果。你需要做的是为代码考虑更好的设计,而不是如何改进当前代码。代码是为了让人类阅读的、优化面向编译器的,因此,找到一种智能的方法来解释你在尝试做的是什么(在代码中)而不是使用更少的话语来表述。通过懒惰(评估)Lisp很久以前就这么做了,而现在大多数语言都是这样做的。例如,Python有yield语句,它将停止当前函数的执行并立即返回值,只有在再次调用该函数时才会产生新值。如果你将使用yield的函数链接起来,则不需要像保留返回列表的函数那样多的内存。在团队/工作上code review并不是为了彰显风格花点时间进行code review,指出架构或设计问题,而不是代码样式(风格)问题。没有人真正喜欢那些在code review中写“你在这一行中留下空白了”或“括号前缺少空格”的人。现在,如果你确实发现了架构或设计问题,那么你可以顺便说一下代码风格问题。代码格式化工具还可以,但它们也不是无往不胜的团队可能想要避免在code review中讨论样式,因而可能会考虑使用代码格式化工具在提交之前自动格式化代码。是的,这部分解决了这个问题,但是还有一个小问题:我们人类不像计算机那样能灵活地阅读代码,计算机可读的内容可能无法被人阅读。当然,有人试图在有利于人类阅读的方面创造一些启发式方法,但这并不意味着这些方法正确。如果你使用代码格式化工具,请使用它来找出最能更改代码的位置。你可能需要简化这一部分的代码,以避免它出现混乱。代码风格:遵循它就是了如果你的项目具有已被定义的代码样式,则必须遵循它。有时可能不清楚(“这个结构/类应该是单数还是复数”?),但请尽力遵循它。...除非代码样式是Google Code样式(完全个人观点,你不同意也没关系)每次谷歌发布自己的编码风格,都是一场垃圾焚烧。社区之前采用了更好的风格方式,谷歌带来一个与此很不相同的的风格,只是为了能使其在自己名下。C / C ++只有一种编码风格:K&R(再次,完全个人意见)其他所有编码风格都是错误的。(笑)Python只有一种编码风格:PEP8社区(大部分)使用PEP8风格,遵循它,那么你的代码可以顺利地与生态系统中的其他部分集成。显式优于隐式你知道什么是有史以来最糟糕的函数名称之一吗?sleep()。睡了多久?是几秒还是几毫秒?对你使用的东西要表达地明确一些,sleepForSecs和sleepForMs并不完美,但比一个单纯的sleep更好。(当你编写应用程序命令行界面或其配置文件时,请考虑这一点。)(我可以在这里抛出整个“Python之禅”,但我正在努力专注于讲个人的,直接的体验。)公司想要专才,但全才在公司待的时间更长如果你对单一语言了解很多,那么它可能会让你更容易找到一份工作,但从长远来看,一门语言的使用可能会消失,你就需要再学一门别的语言了。适当了解许多门其他语言有助于长远发展,更不用说这可能有助于你想出更好的解决方案了。“一种不能影响你对编程的思考方式的语言,不值得了解。”——Alan Perlis很长一段时间,我遵循着一个简单的编程规则:我在家里用来玩的语言不应该是我在工作中使用的语言。这使我能够接触到后来我在工作代码库中应用的新内容。我通过编写Rust代码了解了泛型如何在Java中工作;我理解了Spring如何完成依赖注入因为我之前有学过如何在C++中实现。心中有用户想一想你将如何使用你从用户那里收集的数据——这在当今“隐私”变为一种奢侈的时代更为普遍。如果你捕获任何使用数据,请记住保护它免遭未经授权的使用。处理用户数据的最佳安全方法是压根不捕获它你可以确定,在某些时候,数据会因某些安全漏洞或人为干扰而泄漏。如果你没有捕获任何用户数据——或以匿名方式存储——你将不会遇到任何问题。记下来那些“让我花了一个多小时才解决的愚蠢失误”我尝试过,但从未真正建成过一个列表来记录那些需要花一个多小时才能修正的失误,这种失误仅仅是“忘了添加依赖”或“添加注释”一类,可我不止一次与这些愚蠢的失误作斗争了。但你应该尝试保留一个列表来记录那些让你花了一个多小时才解决的愚蠢失误,因为有了它以后你解决起这类失误来要更快一些。如果它无法在你的计算机上运行,那么你就有麻烦了我看过很多系统永远无法在孤立的计算机上运行,比如开发人员工具,因为系统需要在专门的环境中运行。这真的会扼杀生产力。如果你的系统将在一个专门的环境中运行——包括“云”——那就去找可以抽象你所用之物的东西。例如,如果你使用的是AWS SQS(队列),请找到一个可以抽象队列工作方式的库,这样你也可以使用RabbitMQ了,就可以在你自己的计算机上轻松运行了。如果你使用的是非常专门化的东西,你可能必须自己编写抽象逻辑了,将其与主系统隔离,这样你就可以安心开发主要产品。个人生活该停下来的时候,就停下来吧要知道自己什么时候写不动代码了,要知道自己什么时候学不动了......不要强迫自己,不然将来只会使事情变得更糟。有一次偏头痛时(不严重,但也不算轻),我试着坚持继续写代码。结果第二天,当我好点了的时候,我不得不将大部分重写,因为前一天写的实在太烂了。CoC保护的是你,而不是别人当你开始使用任何语言/库/框架时,请检查他们的CoC。这会保护你,不会让你因为没能立马就上手而被别人怼,而不是阻止你告诉别人你的想法。我提这个因为很多人抱怨CoC,但是他们忘记了正是CoC使他们能加入任何项目而不被白眼,被说是“新手菜鸡”或“先去看完文档,否则别来烦我们”。此外,请记住,大多数反对CoC的都是那些希望能直接责骂任何人的人。学会说不有时,你不得不说:不,我不能这样做;不,在这个时间之前完不成;不,我觉得不能做到这一点;不,我写这个感觉不舒服。有一次我不得不对我们的CTO说:“好的,我会做的,但我想说明,我不认同我们正在做的事情。”最后,APP刚好就因为我们做的事情而被禁止了。你负责你代码的使用这很难,非常非常难,这就是“自由”和“责任”之间的区别。写代码没有错,例如,用于捕捉人脸并检测其种族的软件,但你必须考虑它将被用在何处。当还没完成时,不要说“已经完成了”你厌倦了一遍又一遍地运行同样的事情。有时候即使你记得会发生一些小故障,但是因为你累了,你就告诉大家“已经完成了”。——不要那样做。有人会在第一次运行时就遇到故障并立即告诉你它不work。你将从痛苦中了解你自身我们对无法编译的代码会感到很挫败,也会对客户来回询问一些事情而感到愤怒。当发生这种情况时,我们会迁怒于他人。生活就是如此,这些都是难免的。人们之所以会对代码/架构感到生气/烦恼,是出于关心你会发现自己处于硬币的另一面:你将描述一些解决方案,人们会对某些解决方案感到恼火/生气。当人们关心产品/代码时,他们往往会有这种反应。“是的,你不喜欢那种安静的解决方案,因为你太在意了”,这是别人对我的最暖心的赞美之一。从你的烦恼中学习你会烦恼、生气、沮丧和愤怒,你会看到人们因为这些情绪而陷入困境。所以你必须了解它,不要忽视它。我从教训中学到的一件事是,当我感到沮丧时,我会变得非常有侵略性。现在,当我注意到我开始感到沮丧时,我会向其他人寻求帮助。看到其他人也在努力解决你的问题,这真的很治愈的感觉。注意人们对你的反应我有一个“愤怒男人的休息脸”那样一种脸。有时候我一问问题,人们就会稍微后退——就好像我在说他们的解决方案是错的一样。那时我必须补充道,“我不是说这是错的,我只是有点困惑”。这可能会帮助你避免陷入困境。学会识别那些人格有毒的人,并远离他们你会发现那些人,即使他们不对你的事情窃窃私语,他们也会对所有事情都说坏话——甚至是说其他人的坏话——而且是公开地说。远离那些人。你不知道这种态度会让你情绪多么失落。谨防微观侵略“微观侵略”(Micro-aggressions)是每次小剂量的侵略性评论。就像有人一直称你为“那个人”或看似人畜无害地评论你在某些政策中的立场。这种行为很难反击,因为PR不会听从你说的话认为他们这是在攻击你。而且,这种行为很难被发现,因为它们看起来足够小,但是它们会堆积起来,到最后你会一次爆发你所有的愤怒。最好远离,尽可能避免接触。不,我不认为这样的人是“会改正的”(个人意见)有人可能会说“嘿,也许如果你跟那个人说一下,他们就不会那么做了”。就个人而言,我认为他们不会。这种东西对他们来说已经太久了,他们觉得很自然,而且大多数情况下,你才是做错的那个人(因为没有get到他们是在开玩笑,例如,真正的“薛定谔的混蛋”风格。)只有当你意识到自己是那类有毒的人/微侵略者时,才有可能自己改正除非你意识到你表现得像一个有毒的人或是在微观攻击某人,并且意识到你实际上是在搞破坏,不然没有办法改变这些性格特征(再次强调,个人观点)。......大多数情况下,听到别人批评的声音可能会让你觉得,“他们跟我过不去!”英雄项目:总有一天你必须做的事情“英雄项目”是你个人认为可以解决项目中一系列问题的项目/规范变更/框架。它可能是不同的架构、新的框架甚至是新的语言。这意味着你将花费你的空闲时间来写一些已经被应用的/已经存在的东西,只是为了证明自己的一个观点。有时它会告诉你错在哪里。(但不管如何,你都从中得到一些东西。)不要混淆“英雄项目”与“英雄综合症”我至少见过两类这种情况:有人声称项目离了他们就玩不转,或者声称他们不需要任何人的帮助。这是“英雄综合症”,认为有人可以自己独当一面。不要做那种人。知道何时该果断辞职你告诉你的老板你没有按时完成某项工作,因为一些意料之外的原因,他却朝你发飙。你的一个同事不断微观攻击你。另一个是那个一直在做愚蠢恶作剧的家伙,不停说废话以及在背后议论其他的小组。第三个人总是抱怨说,当他不在时,大家的工作就都搞不定了。现在是时候开始投简历了,无论你目前的薪水有多高或项目有多棒。......除非你想在四十多岁时还经常被别人惹恼。IT世界是一个非常小的“蛋”我们这里有这么一种说法:“某事物的世界是一个小蛋”,这意味着你生活在一个小世界里,世界整体很小。IT世界真的很小。记住今天与你一起工作的人,你可能会在15年后与他重逢,这期间你们可能已经各自换过三四份工作了。你会在中途遇到很多其他的I.T.人。他们会谈论自己。无论你说什么/做什么,都会被大家谈论到,一个人会听到并传递给另一个公司,这个公司将传递给其他人,再把故事传递给另一家公司,然后突然,你意识到了,当地没有人会雇用你了,因为每个人都知道你搞砸了一个项目或捶了一个同事的脸。纸质笔记实际上很有帮助我曾经多次尝试“无纸化”。在某些时候,我确实不需要用纸了,但是到最后,在你旁边如果有一个小笔记本和一支笔来让你写下你需要发送数据的那个该死的URL的话,真的挺得劲的。Trello非常酷,但Post-it更好没有什么比在桌子上放一堆Post-it更能显出你是这样一个人了:“我真的很忙,但我忙中又井井有条”。在博客中记录你笨手笨脚的解决方案仍然比什么都不写要好你可能会觉得“我没有准备好谈论这个”或“这太愚蠢了我不应该谈论这个”。创建一个博客,发布你那些看起来笨手笨脚的解决方案。不管怎么说,它们肯定还是比某些人的解决方案更聪明。此外,稍后再回来写下更好的解决方案,挑战你自己之前的方案。以显示你的成长。除此之外,博客还可以帮助你保存笔记或待办事项。...但请关闭评论发布你笨手笨脚的解决方案的一个问题是,这会吸引一些只想惹毛你的人。“这太愚蠢了”,他们会说。可能会有人说,“你好傻”,而他们不知道谁才真的傻。把评论关了。不要让那些人阻止你。把你的笨手笨脚的解决方案发布到网上不要只把那些“很酷,近乎完美”的项目放到Github上,你完全可以表现出来,在某些时候,你只是初学者。毕竟你总是可以随时返回并修改代码。(或者说不要:我仍然拥有我的第一个Python项目的公共repo,看起来我刚刚将Java翻译成Python,而不包含有Python特性的部分。)列出“我不知道的事情”著名物理学家理查德费曼保留了一本标题为“我不知道的东西”的笔记本。当你发现一些看起来很酷的东西并且你想知道更多时,创建一个标题为“我不知道的东西”的文件/注释/任何内容都行,然后记下你发现了的/弄清楚了的东西。原文:https://blog.juliobiason.net/thoughts/things-i-learnt-the-hard-way/

  • 物联网软件开发是一个雷区。市场需要高质量,可扩展,强大,安全且用户友好的解决方案

    物联网软件开发是一个雷区。市场需要高质量,可扩展,强大,安全且用户友好的解决方案,物联网开发团队必须重新评估其计划和工作流程,以便将所有内容考虑在内。下面列出了物联网项目面临的七个软件开发挑战。由于需求强劲,物联网初创公司和开发公司之间的激烈竞争以及缺乏普遍接受的标准,导致程序员不断寻求新的实践和更新的协议。只有严格的方法才能实现每个物联网软件问题。1)操作系统考虑因素在开始IoT应用程序开发之前,应该仔细考虑几个技术因素。首先,团队必须评估他们将使用的物联网设备。与传统桌面不同,物联网设备功能强大,内存容量相对较小。这意味着开发人员必须选择合适的操作系统。它应该适用于设备的功能和功能要求。最新的物联网开发人员调查显示,Linux是物联网微控制器,受限设备和网关的首选。2)选择网关在物联网网关方面,它们是连接所有元素的关键。不同的设备可以具有不同的连接协议:蓝牙,Wi-Fi,串行端口,Zigbee,并具有各种能量配置文件。网关位于连接的设备,物联网传感器和云之间,因此整个物联网生态系统依赖于它们。戴尔技术,英特尔,Nexcom和其他顶级供应商提供的现代智能网关具有一些常见的强制功能,可使开发人员的工作更轻松。只需选择符合您的物联网应用要求的那个。您将不得不考虑接口和网络规格,额定功率,内存容量,开发环境和其他参数。默认情况下,应保证设备之间的安全,私密和可靠通信。3)确定正确的物联网平台不熟练的开发人员希望从头开发软件。为什么重新发明轮子?这就是物联网平台派上用场的地方,因为它们提供了一些工具组合,可以将您的物理对象联机。平台市场巨大且令人困惑,因此请确保您明智地选择。您首选的平台应提供:a.连接b. 安全c.可扩展性d.易于集成e.可用性但是,物联网开发人员应该意识到智能工厂的平台可能不适合连接汽车或能源解决方案。有些公司甚至选择使用生产过程中的实际数据来构建真实的测试平台来确定合适的平台。4)关于安全性你有没有听说蒂姆卡德莱克的这个IoT笑话?“物联网中的S代表着安全。”物联网中没有“S”。根据定义,物联网技术包括许多连接设备,因此黑客有多个目标来扫描漏洞。并非所有形成网络的设备都经过全面的渗透测试。在这里,整个系统受到威胁。Gartner表示,到2020年,所有发现企业攻击的25%将涉及物联网,只有10%的IT安全预算将用于保护系统免受这些攻击。对于从事物联网项目的开发人员来说,网络攻击的数量将继续增加,安全性是一个巨大的挑战。在概念阶段,保护程度在很大程度上取决于公司准备投资安全专业知识的程度。要减少攻击和未经授权访问的可能性,请使用:a.SSL/TLS加密技术b.孤立的VLAc.独立企业VPNd.现代和更新的反病毒e.最终用户和机器到机器认证f.用于Web开发和设计的Vetted框架g.使用传统保护和控制方法的企业安全架构应尽早更新,以应对当今物联网的新挑战。5)全面控制质量质量保证是物联网软件的另一个投标点。由于物联网设备不仅用于仓库的温度控制,而且还用于智能医疗等许多领域,测试应该是彻底的。从字面上看,任何小问题都可能致命。确保从一开始就在软件开发过程中包含安全测试。要优化流程,请查找不需要针对每个版本进行测试的模块。查找已通过安全测试的协议,并在接下来的几个版本中保持不变。除安全测试外,您还应确保可用性和兼容性。在项目发布后提供技术支持也是一个很好的电话。6)用户友好的设计消费者物联网应用应该是设计驱动的,并且尽可能简单;没有人想学习更新智能手表的手册(对不起,技术作家)。用户友好的设计对于工业物联网初创公司也很重要,因为它们应该专注于数据可视化和快速决策。因为在物联网工作流程中,每个设备,事物和人员都在相互通信,物联网开发人员和设计人员之间的密切合作必须确保:a.安全但简单的身份验证b.设备和系统之间的无缝过渡c.个性化用户体验并根据行为模式调整产品d.整个物联网系统的统一环境7)跨平台部署物联网生态系统包括具有不同体系结构,协议和操作系统的设备。所有这些变量应该结合起来并无缝地工作。因此,互联网工程任务组(IETF),电气和电子工程师协会(IEEE)以及其他着名组织提出了跨平台部署的开放标准和架构模型。它们不断更新,物联网服务应使用这些最佳实践来确保互连通信。定义标准:尽管在过去几年中物联网设备的采用有所增长,但在物联网软件的开发中仍有许多问题需要解决。现在,物联网公司和初创公司应该了解他们以前没有考虑过的细节。采用公认的物联网项目标准将使我们能够部分解决一些发展挑战。特别是,我们可以提高物联网应用程序的安全性及其跨平台部署。然而,由于物联网是一个相对较新的领域,标准仍在进行中。一段时间过去,直到物联网开发社区普遍认可它们。

  • TOP

  • 关于我们

    上海求创科技有限公司成立于2001年,是一家专注于为客户提供高端网站策划、网站建设、网页设计、品牌网络营销以及相关的基于互联网应用服务的专业公司。

    更多

    全国客户服务热线

    400-889-1636

    网站建设,网站制作,企业网站建设,网上商城,网站推广,域名注册,求创科技-微官网 网站建设,网站制作,企业网站建设,网上商城,网站推广,域名注册,求创科技-手机网
    友情链接: 域名超市 | 苏州网站优化 | 营销型网站建设 | 企业网站建设 | 网页设计 | 网站建设 | 网站优化 | 网站设计 | IPv6 升级 | 微信开发 | H5开发 | 系统开发 | 网站维护 | 海外社会化媒体推广 | 上海网站设计 |
    热线电话:400- 889-1636 业务部:sales@dn.cn 售后服务:service@dn.cn 投诉邮箱:info@dn.cn
    地址:上海市松江区谷阳北路2399弄 御上海37号602室 邮政编码:201600
    版权所有©上海求创科技有限公司 沪ICP备13005298号-24  网站地图 沪公网安备 31010602003962号