巨石加密_缓解巨石
巨石加密
by Ian Belcher
伊恩·贝尔彻(Ian Belcher)
我们如何将技术堆栈转向基于服务,以开发人员体验为中心的设计 (How we pivoted our tech stack to a service-based, developer experience-focused design)
This article documents the problems we experienced with monolithic architecture, our transition to a new service-based system, and the results we have seen from its implementation so far.
本文介绍了整体架构所遇到的问题,向新的基于服务的系统的过渡以及迄今为止从其实现中看到的结果。
问题 (The problem)
In 2015 we launched a minimum viable product — a monolith, built on top of a CMS running within a LAMP stack. The CMS in question is respected but has reached a point of decline in its lifecycle, arguably from poor management.
2015年,我们推出了最低可行的产品- 整体式产品,该产品基于在LAMP堆栈中运行的CMS构建。 有争议的CMS得到了尊重,但其生命周期已达到下降点,这可能是由于管理不善所致。
The costs relating to the development and delivery of our project had begun to exponentially increase:
与我们的项目的开发和交付有关的成本已开始成倍增加:
- Our only feasible option was to scale vertically and it was a lot harder to implement high availability or redundant systems. Continual upgrades to our main host server were met with increases to our resource unit costs.我们唯一可行的选择是垂直扩展,而实现高可用性或冗余系统要困难得多。 不断升级我们的主主机服务器可以增加资源单位成本。
We were exclusively locked into a language and its performance. PHP is great for certain tasks, but not every task. In fact, it fails considerably for certain things where other languages shine.
我们被专门锁定一种语言及其性能。 PHP对于某些任务非常有用,但对于每个任务却不是。 实际上,对于某些使用其他语言的语言来说,它会严重失败。
- The internal design of the CMS performed terribly by today’s standards. Some core hacks improved this by orders of magnitude, but the site still performed poorly due to a number of suboptimal, upstream design decisions.CMS的内部设计按当今的标准执行得非常糟糕。 一些核心技巧将其改进了几个数量级,但是由于许多次优的上游设计决策,该站点的性能仍然很差。
- As we continued to grow the project from its roots as a minimum viable product, we reached a complexity point where more additions or changes to functionality were met with a constantly increasing cost factor.随着我们从最小的可行产品的根源继续发展该项目,我们到达了一个复杂点,在不断增加的成本因素下,功能性得到了更多的增加或改变。
- Due to increasing complexity, the developer experience sucked. Many developers will attest that once a project grows beyond a certain level of complexity, good, quality development drops off due to changes in one area having unforeseen consequences in other seemingly unrelated areas.由于复杂性的增加,开发人员的经验糟透了。 许多开发人员将证明,一旦项目增长到一定程度的复杂性之后,由于一个领域的变化会在其他看似无关的领域产生不可预见的后果,因此良好,高质量的开发就会下降。
Using a CMS meant that our product was almost fully dependent on the quality of a team of upstream developers from a small, privately owned company. The decisions they made impacted us. In effect, we were outsourcing many important tasks to this company, such as our security.
使用CMS意味着我们的产品几乎完全依赖于一家小型私有公司的上游开发人员团队的质量。 他们做出的决定影响了我们。 实际上,我们将许多重要任务外包给了该公司,例如我们的安全部门。
The tight coupling within the core CMS system prevented us from trying out new technology. For example, direct interaction with the database could be found in nearly every part of the code-base, removing our ability to change or update the database technology.
核心CMS系统内部的紧密耦合使我们无法尝试新技术。 例如,几乎可以在代码库的每个部分中找到与数据库的直接交互,从而消除了我们更改或更新数据库技术的能力。
We reached two important conclusions: Our monolith tech stack would continue to impede us from achieving our short-term goals, and our long-term goals would quickly become impossible from a product perspective and a human capital perspective.
我们得出两个重要结论:我们的整体技术堆栈将继续阻碍我们实现短期目标,而从产品和人力资本的角度来看,我们的长期目标将很快变得不可能。
Like any good, learning organization, we weren’t going to make these mistakes again. After many hours of further consideration we arrived at this hypothesis:
像任何一个好的学习型组织一样,我们不会再犯这些错误。 经过数小时的进一步考虑,我们得出了以下假设:
Monolith design facilitates, imposes and in some regards is itself, an anti-pattern.
整体设计促进,强加,并且在某些方面本身就是一种反模式。
Good development is about clear separation of concerns. Good development is about high classification and well-designed encapsulation of data and functionality.
良好的发展关系到明确的关注点分离。 良好的开发涉及数据和功能的高度分类和精心设计的封装。
The God class anti-pattern and the Law of Demeter tell us that we should limit knowledge in any specific area to only that which is required. So why are these principles often only implemented at a language level?
上帝的反模式和得墨of耳定律告诉我们,我们应该将任何特定领域的知识限制为仅需要的知识。 那么,为什么这些原则通常仅在语言级别实施?
In an abstract way, monolith systems are a ‘God class’. They function as a single, heavy controller — a global object that is injected upon instantiation with all of your system’s dependencies. They impose constraints such as operating system or language choices, where certain tasks are much better suited to other configurations.
从抽象的角度讲 ,整体系统是“神类”。 它们充当单个重型控制器 - 一个 实例化时注入的全局对象,其中包含系统的所有依赖项。 它们强加了诸如操作系统或语言选择之类的约束,其中某些任务更适合于其他配置。
By definition, a monolith has full knowledge of the entire system. Therefore, in most cases, a developer working on a monolith also requires full knowledge to work on that project efficiently and effectively.
根据定义,整体具有对整个系统的全面了解。 因此,在大多数情况下,从事整体工作的开发人员还需要充分的知识才能有效地对该项目进行工作。
The developer needs this knowledge to make correct decisions that relate to the clear-cut separation of responsibilities between different areas of the code-base. When all of your classes are running ‘alongside each other,’ it is easy to make the wrong decision as to what should be done and where.
开发人员需要这些知识来做出与在代码库的不同区域之间明确划分职责相关的正确决策。 当您所有的类都“并排运行”时,很容易对应该做什么和在哪里做出错误的决定。
我们的解决方案 (Our solution)
Based on our hypothesis, we concluded that the current system was unsalvageable, and that a full rebuild under a service design pattern would produce a system that avoided the various issues we identified.
根据我们的假设,我们得出结论,当前系统是无法挽救的,并且在服务设计模式下进行全面重建将产生一个避免我们发现的各种问题的系统。
We created a matrix outlining what we wanted to achieve with the new system:
我们创建了一个矩阵,概述了我们希望通过新系统实现的目标:
Developer Experience (DX) defines the first half of our matrix. The desired calibre of developers we want are those looking for an opportunity to work on things they enjoy and are challenged by. To create a great DX, our code base needed to provide an ecosystem that talented developers would find engaging, while avoiding the pitfalls we had experienced in monolith design.
开发人员经验(DX)定义了矩阵的前半部分。 我们想要的开发人员的理想素质是那些寻找机会从事他们喜欢和受到挑战的事物的开发人员。 为了创建出色的DX,我们的代码库需要提供一个才华横溢的开发人员可以参与的生态系统,同时避免我们在整体设计中遇到的陷阱。
Product Delivery shapes the second half of our matrix. The phrase ‘content is king’ still holds true, but the performance of a website has also become a major factor from both a user perspective and search engine perspective. Fostering great DX was important, but it was imperative that the new website performed better for our users.
产品交付塑造了矩阵的后半部分。 “内容为王”一词仍然适用,但从用户角度和搜索引擎角度来看,网站的性能也已成为主要因素。 培养出色的DX很重要,但是必须让新网站对我们的用户有更好的表现。
Here is a breakdown of the four main components of the matrix and what we aimed to achieve.
这是矩阵的四个主要组成部分的细分以及我们要实现的目标。
敏捷 (Agility)
Complexity kills. Complexity sucks the life out of users, developers and IT. Complexity makes products difficult to plan, build, test and use. Complexity introduces security challenges. Complexity causes administrator frustration. And as time goes on and as software products mature — even with the best of intent — complexity is inescapable. — Ray Ozzie
复杂性杀死。 复杂性使用户,开发人员和IT失去生命。 复杂性使产品难以计划,构建,测试和使用。 复杂性带来了安全挑战。 复杂性会使管理员感到沮丧。 随着时间的流逝以及软件产品的成熟(即使有最好的意图),复杂性也是不可避免的。 — 雷·奥兹 ( Ray Ozzie)
Solution: Reduce Complexity = lower financial cost, greater DX, lower learning curves.
解决方案:降低复杂性=降低财务成本,增加DX,降低学习曲线。
Complexity within a system behaves like a virus. The more complexity that is present, the more it grows. Reducing and segregating complex parts of the system stops more complexity from growing in other areas.
系统内的复杂性就像病毒一样。 存在的复杂性越高,增长的速度就越大。 减少和隔离系统的复杂部分可以防止其他方面的复杂性增加。
Service-based design can quarantine the virus. A monolith facilitates the spreading of complexity. (During the initial development of the new system, Conway’s Game of Life served as a good reminder of this fact).
基于服务的设计可以隔离病毒。 整体结构有助于分散复杂性。 (在新系统的最初开发过程中, Conway的“生命游戏”很好地提醒了这一事实)。
When the code is simple, it is easier to make it efficient and effective at what it does and more enjoyable to work on. The ‘art’ of the developing becomes the output, not the code itself.
当代码很简单时,使代码更高效,更有效,并且工作起来更有趣。 开发的“艺术”成为输出,而不是代码本身。
Separating out areas of concern into system level boundaries (which services do) means developers no longer need full knowledge of the entire system to work on it effectively. They are given a defined interface (for example, a HTTP API, socket or AMQP message) at a system level, not a language level, and can be assigned actual responsibility for that service.
将关注的区域划分为系统级别的边界(服务可以做到)意味着开发人员不再需要完整的系统知识就可以有效地进行工作。 在系统级别 (而不是语言级别)为它们提供了定义的接口(例如,HTTP API,套接字或AMQP消息),并且可以为他们分配对该服务的实际责任。
This separation means a developer who is given responsibility for a service can effectively change the underlying technology (such as what language, OS or persistence technology is used) without other team members knowing. This allows for performance trials and deep dives and prevents the need to up-skill the whole team to account for changes.
这种分离意味着负责服务的开发人员可以在其他团队成员不知情的情况下有效地更改基础技术(例如,使用哪种语言,操作系统或持久性技术)。 这样可以进行性能测试和深入研究,并避免需要提高整个团队的技能来应对变化。
The reduction of complexity and segregation that results from service design creates a code-base with a high agility factor. New developers can be committing on their first day, because reading and understanding the entire code base at a service level typically involves a few hundred lines of code.
服务设计导致的复杂性和隔离性的降低创建了具有高敏捷度因子的代码库。 新开发人员可以在第一天就下定决心,因为在服务级别阅读和理解整个代码库通常涉及几百行代码。
稳定性 (Stability)
Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. — Alan Kay
如今,大多数软件非常像埃及的金字塔,成千上万的砖块彼此叠放,没有结构上的完整性,只是由蛮力和成千上万的奴隶完成的。 — 艾伦·凯
Solution: Minimize and mitigate dependencies = lower exposure to industry volatility and breakages, increased management ability and greater DX
解决方案:最小化和减轻依赖关系=降低行业波动和破损的风险,增强的管理能力和更大的DX
The volatility and rate of change in the software industry surpasses most other industries, yet most people in the software industry choose to accept these risks rather than mitigate them.
软件行业的波动性和变化率超过了大多数其他行业,但是大多数软件行业的人选择接受这些风险而不是减轻它们。
A number of wide scale breakages resulting from a lack of mitigation of upstream changes have already occurred this year (see here and here).
由于缺乏缓解上游变化的影响,今年已经发生了许多大规模破损(请参见此处和此处 )。
Service design fosters greater separation, specificity, and the appropriate use of dependencies. This allows planned integration of upstream changes — not just when your CI breaks.
服务设计可促进更大的分离性,特异性和对依赖关系的适当使用。 这允许按计划整合上游变更 -不只是您的CI中断。
Using third party code (especially with standard package workflows such as npm et. al.) is the same as giving developers outside of your team write access to your code-base without the normal vesting such as PR’s or reviews. The inclusion of third party code needs to be given good cause, carefully chosen and then committed to. Better managing dependencies means that your team can focus more on building, not retrofitting.
使用第三方代码(尤其是在标准的软件包工作流程(例如npm等)中使用)与为团队外部的开发人员提供对代码库的写访问权限相同,而没有常规的权限(例如PR或评论)。 包含第三方代码需要有充分的理由,要仔细选择然后再承诺。 更好地管理依赖关系意味着您的团队可以将更多的精力放在构建而不是改造上。
可扩展性 (Scalability)
At a sysops level, it is well known that service design enables more manageable scalability compared with monoliths. It is common for teams to migrate from monolith design for this reason.
在系统操作级别,众所周知,与整体设计相比,服务设计可实现更可管理的可伸缩性。 因此,团队通常会从整体设计中迁移。
What isn’t so apparent before this transition is the resource unit cost reduction that occurs with service design, even on systems that don’t need to scale with demand.
在进行这种过渡之前,还不那么明显的是服务设计会降低资源单位成本,即使在不需要根据需求扩展的系统上也是如此。
Many hosts have greater resource unit costs for larger machines (i.e. $80 will buy 8GB 4 cores 80GB if buying one instance, or 8GB 8 cores 240GB if buying eight $10 instances).
许多主机在较大的机器上具有更高的资源单位成本(例如,如果购买一个实例,则80美元将购买8GB 4核80GB;如果购买八个实例,则将购买8GB 8核240GB)。
This cost reduction comes with the benefit of higher reliability, because service design offers better scope for state management. For example, if a service crashes, your entire system doesn’t go offline — everything continues and that service is restarted and re-added to your cluster.
成本的降低带来了更高的可靠性,因为服务设计为状态管理提供了更好的范围。 例如,如果服务崩溃,则整个系统不会离线 -一切继续进行,该服务重新启动并重新添加到您的集群中。
网站速度 (Site Speed)
A very common mistake was made on our previous monolith site. Our view layer was split across two different technologies : Server-side PHP templates and front end JavaScript. Under these circumstances there were multiple rendering processes that had to take place on both the client side and server side for every page view.
在我们以前的整体网站上犯了一个非常常见的错误。 我们的视图层分为两种不同的技术:服务器端PHP模板和前端JavaScript。 在这些情况下,每个页面视图的客户端和服务器端都必须执行多个渲染过程。
This added a ton of complexity for developers and also slowed the site considerably.
这给开发人员增加了很多复杂性,也大大降低了网站速度。
Solution: Implement classical client-server software design, make the client self sufficient and use the server only for persistence.
解决方案:实施经典的客户端-服务器软件设计,使客户端自给自足,并且仅将服务器用于持久性。
From a model-view-controller perspective, implementing classical client-server software design means your view layer is very well defined and encapsulated into a single area of concern.
从模型-视图-控制器的角度来看,实现经典的客户端-服务器软件设计意味着您的视图层已得到很好的定义,并被封装到单个关注区域中。
Great front end frameworks have become available in recent years which enable this to be done simply and easily.
近年来,强大的前端框架已经可用,这使此操作变得简单而轻松。
On most websites, almost everything required to display a page is delivered repeatedly (HTML structure, CSS, JavaScript) and the server typically acts as the part that populates the data within the HTML structure. It is more logical to deliver the static requirements once, then let the client populate the HTML with the data.
在大多数网站上,显示页面所需的几乎所有内容都是重复交付的(HTML结构,CSS,JavaScript),并且服务器通常充当填充HTML结构内数据的部分。 一次交付静态需求,然后让客户端用数据填充HTML,这更合乎逻辑。
到目前为止我们学到了什么 (What we’ve learnt so far)
Internally we believe we have delivered exceptionally well on the four components of our matrix. In future posts I will be exploring each one separately in more detail and sharing some metrics. In the meantime, here are a few key points we’ve taken away from the process:
在内部,我们认为我们在矩阵的四个组成部分上表现出色。 在以后的文章中,我将分别详细探讨每个方面,并分享一些指标 。 同时,以下是我们从流程中删除的一些关键点:
建立马戏团,而不是管弦乐队 (Build a circus, not an orchestra)
A monolith requires your entire team to be working in the same code space at the same time in a coordinated fashion. Picture an orchestra: A mistake by any member will affect the performance of the entire team.
整体需要您的整个团队以协调的方式在相同的代码空间中同时工作。 想像一个乐团:任何成员的失误都会影响整个团队的表现。
Instead, make your tech production about giving your developers the space they need to do what they do best. Service design allows you to create a set of well performed, isolated ‘acts’.
相反,进行技术生产时要给开发人员足够的空间,使他们可以做自己最擅长的事情。 服务设计使您可以创建一组性能良好的隔离“行为”。
像银行经纪人一样思考,而不是无家可归的人 (Think like a bank broker, not a bower bird)
Upstream dependencies, third party code and tooling can have quick returns but always come with a multitude of implied risks while writing your own ‘fit for purpose’ code will give you more efficiency and lower levels of risk. Continually picking up and collecting dependencies like a bower bird increases your exposure to these risks.
上游依存关系,第三方代码和工具可以快速获得回报,但始终伴随着许多隐含的风险,同时编写自己的“适合目的”代码将为您带来更高的效率和更低的风险。 像领鸟一样不断捡拾和收集依赖物会增加您面临的这些风险。
Instead, think like a bank broker and only choose the safest ‘stocks’ with good ‘returns’ to limit and mitigate your exposure wherever possible.
相反,请像银行经纪人那样思考,并仅选择具有良好“回报”的最安全“股票”,以尽可能限制和减轻您的风险敞口。
服务的行为与定义良好的类相同 (Services act the same as well defined classes)
The behaviour of a service is synonymous with a class within a monolith code-base. They have a public interface, they are constructed with their required dependencies and encapsulate their own data and control its access.
服务的行为与整体代码库中的类同义。 它们具有公共接口,它们以所需的依赖项进行构造,并封装自己的数据并控制其访问。
However unlike classes that run along side each other, it is more difficult for a developer to simply change the design of an interface to suit their needs in a given context. This constraint fosters stronger, interface-centric design which in turn leads to more predictable, higher quality code.
但是,与并排运行的类不同,对于开发人员而言,仅更改接口的设计以适应给定上下文中的需求更加困难。 这种约束促进了更强大的,以界面为中心的设计,进而导致了更可预测的,更高质量的代码。
服务器端渲染与典型软件开发实践相反 (Server-side rendering is the inverse of typical software development practice)
Like applications that run on your computer, gaming console or devices, servers act as a central persistence layer, not the renderer. Rendering the view on the server-side is a throw back to the earlier days of the internet where servers delivered static files. This practice has propagated to today’s web due to the server-only language preferences of web developers.
就像在计算机,游戏机或设备上运行的应用程序一样,服务器充当中央持久层,而不是渲染器。 在服务器端渲染视图可以追溯到Internet早期的服务器交付静态文件的时代。 由于Web开发人员仅使用服务器的语言偏爱,这种做法已传播到当今的Web。
The web browser is a smart, powerful, perfectly scalable and free-to-use resource. Make use of its full potential by producing ‘native’ web pages that run in the browser, not on your server.
Web浏览器是一种智能,功能强大,可完美扩展且免费使用的资源。 通过生成在浏览器而非服务器上运行的“本机”网页来发挥其全部潜力。
后记 (Postscript)
If you enjoyed this article, please hit the heart button below to promote further conversation.
如果您喜欢这篇文章,请点击下面的心脏按钮以促进进一步的对话。
I am CTO at Deckee — we help the boating community find, share and discuss the things they love.
我是Deckee的CTO-我们帮助划船社区 查找,分享和讨论他们喜欢的事物。
Deckee is an affirmative action employer and we are always on the lookout for likeminded, audacious developers. Please ‘inspect’ our site for more details.
Deckee是积极行动的雇主,我们一直在寻找志趣相投,大胆的开发人员。 请“ 检查 ”我们的网站以获取更多详细信息。
翻译自: https://www.freecodecamp.org/news/https-medium-com-deckee-tech-mitigating-monoliths-2a8dcb8603a9/
巨石加密
相关文章:

Python函数中的参数(一)
函数传递参数时的简要关键点: 1、参数的传递是通过自动将对象赋值给本地变量名来实现的。函数参数在实际中只是Python赋值的一个实例。因为引用是以指针的形式实现的,所有的参数实际上都是通过指针进行传递的。 2、在函数内部的参数名的赋值不会影响调用…
LLDB 调试相关
LLDB 初始 LLDB 是一个有着 REPL 的特性和 C ,Python 插件的开源调试器。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。调试器允许你在程序运行的特定时暂停它,你可以查看变量的值,执行自定的指令,并且按照你所认为合适的…

javascript优缺点_为什么要在JavaScript中使用静态类型? 优缺点
javascript优缺点by Preethi Kasireddy通过Preethi Kasireddy 为什么要在JavaScript中使用静态类型? 优缺点 (Why use static types in JavaScript? The Advantages and Disadvantages) We covered a lot of ground in Part 1! With syntax out of the way, let’…

大数的减法函数--c语言
代码展示: http://paste.ubuntu.com/23693598/ #include<stdio.h> #include<stdlib.h> #include<string.h> char * largeDiffer(char *a,char *b){ /* 使用说明 传入的a和b只能为整数 结果为a-b;返回的为字符指针,注意数组不要越…

json 基础
json格式 JSON格式:http://www.json.org/ python和JSON的关系请参考:http://docs.python.org/library/json.html JSON建构有两种结构: 1. “名称/值”对的集合(A collection of name/value pairs)。不同的语言中&#…

iOS 中 load 和 initialize的实现顺序
1 load 函数 调用时机,当类引用进项目的时候执行load函数,在main函数开始之前,与 这个类是否被用到是无关的,每个类的load函数都会自动调用一次。 1 父类和子类都实现load函数的时候,父类的load方法优先于子类 2 类…

需求简报_代码简报:有史以来最怪诞的丑毛衣
需求简报Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事: The geekiest ugly sweater ever: 4 minute read 有史以来最怪异的丑毛衣: 4分钟阅读 Lessons from my post-bootcamp job …

C#内置函数 RunSql的使用
作用批量执行sql语句表达式.RunSQL(SQLStatement,UseTransaction)表达式.一个代表DoCmd对象的变量。注释:sqlstatement参数的最大长度为 32,768 个字符(而"宏"窗口中的 SQL 语句操作参数的最大长度为 256 个字符)。 官方说仅能用于…

swif 在字符串中查找特定字符索引以及改变字符串的指定位置的颜色 字体大小
1 第一种方式 var text "谁包含这个字母";let range:Range<String.Index> text.range(of: "含")!;let end_idx:Int text.distance(from: text.startIndex, to: range.lowerBound);// 打印2print(end_idx);类方法 抽取 // 查找对应索引static func…

SD卡的控制方法(指令集和控制时序)
1.SD卡的命令格式: SD卡的指令由6字节(Byte)组成,如下: Byte1:0 1 x x x x x x(命令号,由指令标志定义,如CMD39为100111即16进制0x27,那么完整的CMD39第一字节为01100111,即0x270x40…

javascript 代码_代码简介:2016年JavaScript的现状
javascript 代码Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事: The state of JavaScript in 2016: 5 minute read 2016年JavaScript状况: 阅读5分钟 Upgrading to macOS Sierra wi…

Unity协程截图,WWWForm、WWW配合上传
先说一下原理。。 截图有两种方法,第一种: Application.CaptureScreenshot(url); 这个API可以截全屏并保存到指定路径 这里我们不采用此方法 下面的代码采用第二种方法,自己建一个Texture2D 这种方法灵活,操作性更高 WWWForm方法是…

OC 的反射机制以及使用场景
OC 的反射机制 一 定义概念 普遍的概念就是类似于java的反射机制,动态机制使得OC语言更加灵活。 反射机制就是可以根据指定的类名获取类的相关信息。 二 作用 1 根据类名获得class // 选择器 和字符串之间的相互转化 FOUNDATION_EXPORT NSString *NSStringFr…

centos 网卡聚合及Cisco交换机链路聚合
一、配置环境 centos 系统。网卡1口和2口做链路聚合。 交换机网口 6口和7口。 二、服务器操作步骤 centos 6 1.创建一个channel bonding interface #vi /etc/sysconfig/network-scripts/ifcfg-bond0 添加如下几行: GATEWAY192.168.10.1 DNS1202.106.0.20 DEVICEb…

graphql redux_如何在Redux应用程序中使用GraphQL
graphql reduxby Howon Song通过宋颂恩 如何在Redux应用程序中使用GraphQL (How to use GraphQL in your Redux app) Fetching and managing data in Redux requires too much work. As Sashko Stubailo points out:在Redux中获取和管理数据需要太多的工作。 正如Sashko Stuba…

原创:去繁存简,回归本源:微信小程序公开课信息分析《一》
以前我开过一些帖子,我们内部也做过一些讨论,我们从张小龙的碎屏图中 ,发现了重要讯息: 1:微信支付将成为重要场景; 2:这些应用与春节关系不小,很多应用在春节时,有重要的…

ubuntu 14.0 下github 配置
一:创建Repositories 1:首先在github下创建一个帐号。这个不用多说,然后创建一个Repositories。 2:然后在ubuntu下安装git相关的东东: 1sudo apt-get install git-core git-gui git-doc -y 3:在ubuntu本地创建一个ssh密匙: 1ssh-k…

OC 消息转发实现多继承
消息转发实现多继承 在OC 中,一个类只支持单继承,但是可以通过别的手段实现多继承。 利用消息转发实现多继承。 在OC 中,对象调用方法实际是在发消息,对象接收到一条消息的时候,消息函数随着对象的isa 指针到自己的…

chatscript_如何使用ChatScript构建您的第一个聊天机器人
chatscriptby Giorgio Robino通过乔治罗宾诺(Giorgio Robino) 如何使用ChatScript构建您的第一个聊天机器人 (How to build your first chatbot using ChatScript) 10–10–2018: article updated with new github repo url.2018年10月10日:文章更新为新的github r…

web安全浅析
就之前本人主持开发的金融产品所遇到的安全问题,设计部分请参见:http://www.cnblogs.com/shenliang123/p/3835072.html 这里就部分web安全防护就简单的交流: 1.1系统安全 1.1.1 客户端脚本安全 (1)跨站脚本攻击&#…

HDU 1556 Color the ball
题解:基础的树状数组区间修改,单点查询。 #include <cstdio> #include <cstring> int c[100005],a,b,n; int modify(int x,int num){while(x<n)c[x]num,xx&-x;} int query(int x){int s0;while(x>0)sc[x],x-x&-x;return s;} …

OC协议实现多继承
协议实现多继承 协议实现多继承的话,只是简答的提供了接口,并灭有提供实现的方式。 A #import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGINprotocol StuAProtocal <NSObject>// 学生A 会游泳 - (void)swimming;endinterface Stude…

扶梯正确使用_乘坐自动扶梯解释CSS浮动
扶梯正确使用by Kevin Kononenko凯文科诺年科(Kevin Kononenko) 乘坐自动扶梯解释CSS浮动 (CSS Floats Explained By Riding An Escalator) 如果您曾经跳过自动扶梯,那么您可以快速了解浮动。 (If you have ever jumped on an escalator, then you can quickly und…

安卓学习-界面-ui-ListView
ListView继承自AbsListView AbsListView属性 XML属性代码说明 android:choiceMode setChoiceMode(int choiceMode) AbsListView.CHOICE_MODE_SINGLEAbsListView.CHOICE_MODE_MULTIPLEAbsListView.CHOICE_MODE_MULTIPLE_MODAL none :无选择模式 singleChoice:允许单…

swift 浮点型字符串的运算
// 1 两个浮点字符串之间的运算 let str1 "1.3"; let str2 "2.4"; let val1 Double(str1); let val2 Double(str2);let val3 CGFloat(Double(str1)!) * CGFloat(Double(str2)!);print(val3);// 2 string 转 double 不失精度 let formattor NumberFo…

为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)
by Preethi Kasireddy通过Preethi Kasireddy 为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门) (Why use static types in JavaScript? (A 4-part primer on static typing with Flow)) As a JavaScript developer, you can code all day …

客户端如何连接 DataSnap Server 调用服务的方法
一般http访问的地址是 http://localhost:8099/datasnap/rest/TServerMethods1/EchoString/abc 一、用FDConnection1连接Datasnap服务器 FireDAC 连接Datasnap服务端。这个是tcp协议连接通讯,长连接。服务端不是没个方法都建立实例释放实例,而是连接的时…

Solr_全文检索引擎系统
Solr介绍: Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务。Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。 Solr的作用: solr是一个现成的全文检索引擎系统, 放入tomcat下可以…

swift 数组 filter reduce sort 等方法
数组的常用方法 swift 数组有很多的操作方法,但是用的时候用常常想不起来,就列出来看看 map 和 flatMap对数组中的元素进行变形操作filter主要对数组进行过滤reduce主要对数组进行计算sort对数组进行排序forEach循环遍历每一个元素min 和 max找出数组中…

im和音视频开发哪个更好_找时间成为更好的开发人员
im和音视频开发哪个更好There’s no time for anything. At least that’s how it feels doesn’t it? No time to learn all the things you think you need to learn to stay ahead of the curve. No time to go back and refactor that ugly piece of code. It works (sort…