敏捷水手——单体法到微服务之旅

\

本文要点

\\
  • 探究持续四年多的渐进式改革是什么样子;\\t
  • 探索为什么在变革软件和组织设计时要遵循康威定律;\\t
  • 看看如何将领导力应用到不同的团队、领域和层级;\\t
  • 举例说明变革管理如何依赖于理念和一贯的长远目标;\\t
  • 了解从职能型团队到跨职能团队的变革需要做多少工作以及能带来多少回报。\
\\

简介

\\

过去几年,eSailors IT Solutions在技术和组织层面进行了重大变革:从功能筒仓到跨职能团队,从看似装配线的工作流到动态循环,从单体平台到微服务,从层次化的命令-控制到团队运作的领导力。本文将简要介绍他们的变革之旅。本文将带你了解大约四年之前我们从哪里开始,经历了哪三个主要的变革阶段才成为现在这个样子。对于每个阶段,本文都将概要地介绍以下几个方面的内容:

\\
  • 我们当时的组织设置;\\t
  • 主要的技术栈;\\t
  • 我们面临的最重要的挑战;\\t
  • 我们希望取得的变革成果以及我们实际取得的成果;\\t
  • 我们的经验教训以及它们如何推动了进一步的改进。\

贯穿本文的一个重要主题是康威的假说“设计系统的组织……其产生的设计和架构等价于组织间的沟通结构。”1我们将把这一理论作为一面特殊的镜子,用它来照一照我们自己的历史。将组织设计和软件设计对照有什么意义?我们从对公司沟通模式的探究中学到了什么?为什么康威定律仍然在伤害着我们?

\\

我们从哪里开始

\\

以前,在汉堡,对于那些只有75名工程师、全部员工大约只有120多人的小型软件公司而言,生活很简单。面对着大约300万的客户,我们的点子来自当事人、市场或法律部门。我们的平台平均要服务于大约35万活跃客户,每年2.5亿订单。工作流程是由项目经理组织的。知识被职能筒仓完全隔离:软件部门负责编写特性,质量保证部门负责保证质量,运维部门负责确保软件的稳定运行。如果我们需要修改任何基础设施组件(如增加新服务器、不同的操作系统程序包),一个隶属于其他部门(及国家)的团队就需要进行必要的安装准备。由于各种各样的预算、合作和/或沟通问题,这种方法经常导致严重的延期。

\\

b347254d303c9cb7494227fa941bbc14.png

\\

图1:eSailors的装配线

\\

我们那时的组织设置是什么样子?

\\

我们那时的组织设置是什么样子?如图1所示,我们的工作流组织非常像老式工厂里的一条装配线。大多数员工都是在那五个部门(项目管理/市场营销、设计、开发、QA、运维)的其中一个部门里工作。每个部门都有自己的管理结构,都有团队负责人和部门主管。遵循着特定的冲刺周期和步骤,软件工件从一个部门传递到下一个部门:

\\
  • 步骤1:市场营销部门、法律要求或项目经理界定特性,但不进行有效的预验证或评估;\\t
  • 步骤2:设计部门根据经验进行设计;\\t
  • 步骤3:开发部门在一个软件工件中实现功能,团队使用Scrum,但对于UI变更,会咨询一个专门的前端团队(3周);\\t
  • 步骤4:QA部门测试(2周);\\t
  • 步骤5:为了防止基础设施方面的更改,基础设施团队会准备系统;\\t
  • 步骤6:Ops团队将软件工件部署到生产环境,并对其进行维护;\\t
  • 步骤7:一个专门的团队进行Bug修复。\

简而言之,我们的价值流是瀑布式Scrum2。就是说,我们在传统结构下实现了Scrum,我们的敏捷理念所关注的是局部,而不是整个系统。此外,我们在很大程度上还是筒仓形式的组织,采用传统方式进行管理,以决策制定为中心,沟通通常是单向的,由自上而下的策略和自下而上的报告所主导。我们的组织设置如图2所示:

\\

74cb12b6ee360f0b141d21b5874469b6.png

\\

图2:eSailors最初的组织设置

\\

为了变得更加敏捷,每个产品开发团队都竭尽全力。图3展示了我们的团队设置。在本图及后续出现的图片中,DEV表示开发人员,QA表示质量保证,PM表示项目经理。即使每个团队都有一名质量工程师,最终的质量检查和软件审批也还是由一个专门的质量部门所完成。团队的质量工程师必须以一种质量部门审批时能够执行的方式准备测试。

\\

b40164192c01293761b84b6d099dfdfa.png

\\

图3:eSailors最初的开发团队设置

\\

我们的技术呢?

\\

我们一点也不感到奇怪,这种模式反映在了我们的软件架构中。技术被设计成一个单体平台,基于一个紧耦合的代码库构建,总是作为单个软件进行部署。我们的代码大约有80%都打包在一个工件中。eSailors的工程师习惯将这个平台称为“大泥团”,因为它没有一个可理解的架构,而且很难扩展和维护。部署是通过一个复杂的工具完成的,而且还受限于版本控制系统的逻辑。有时候,提交几个小时后才看到单元测试失败。由于构建和部署过程的复杂性,这个技术栈让变更变得相当困难。

\\

我们如何设法变革我们的流程?

\\

康威定律指出,“设计系统(广义而言)的组织其产生的设计和架构等价于组织间的沟通结构”。我们那时从对现状的审查中了解到了什么?我们如何行动起来设置这两种结构?我们的计划是什么,而我们实际上取得了什么样的成果?

\\

我们从康威定律中汲取的其中一个最重要的教训是:转化成创新性产品以及缩短上市时间不能只依赖于技术变革。相反,组织变革和技术息息相关,需要对这两个维度都进行检查和相应的调整。虽然这在概念上听起来很简单,但改变我们的组织设置和思维花费了我们很长时间,而且现在仍然是我们需要首先处理的问题。

\\

5a9ee7edfc004aaf63a2a8ed2dc50443.png

\\

图4:第一步:新的团队设置

\\

检讨我们的装配线问题,我们决定创建跨职能团队,由他们对整个系统开发的生命周期负全责。为了达到这个目标,我们从组织设置入手。我们解散了Bug修复团队,让特性团队为自己的错误负责。这也可以帮助他们更好地理解操作上的需求。我们认为,跨职能团队应该包含全栈职责,所以我们将原先共享的前端团队的成员分配到特性团队。同时,我们将冲刺周期改为两周,一周用来开发,一周用来测试。

\\

我们希望从这些组织变革中得到什么呢?从根本上说,我们希望提高软件质量,缩短交付时间。我们实际上得到了什么呢?好了,我们的结果让人觉得有点矛盾。一方面,加大团队的自主权和责任感让人们更清楚问题所在。但是,所有团队都开始寻找可持续的解决方案,而不是修复问题。这种情况就是由图4所示的新的组织设置所导致的。

\\

让开发团队负责Bug从许多方面改善了运维和开发部门之间的沟通。DevOps交流项目启动(开发人员在一个冲刺期间呆在Ops部门,反之亦然)。开发人员主动请求参与呼叫中心的工作及使用监控工具。组织文化日益趋向于端到端职责,这种变化越来越明显。开发人员、运维人员和基础设施人员开始定期讨论系统和管理问题。这是进一步改进的关键。简化后的装配线如图5所示。

\\

73d962666f0e44e70dabacd210095949.png

\\

图5:第一步:管道

\\

不出所料,领导力在许多层面得到了增强。过去,作为功能专家,工程师们习惯于构建自己的I型技能集。现在,他们开始让自己向着跨职能团队的T型领导者发展。团队自己承担了技术决策的职责,而不是专注于一种核心的架构。

\\

另一方面,我们的共享代码库还是保持不变,还是会导致小的改进开发成本很高。

\\

而且,我们开始认识到,我们的Scrum方法在许多方面都是失败的。它没有为我们提供正确的指导,却首先增加了我们的负担。我们经常因为需要修复即将出现的Bug而完全忽视了我们的冲刺承诺。将大的特性分割成较小的故事然后排定它们的优先级,这项工作费时费力。也许,最大的阻碍是作为我们主要客户的项目管理和市场营销部门的无法撼动的瀑布式思维。我们使用Scrum框架,但是在实现过程中没有采用特性范围。团队的产品经理充当了管理者,将瀑布项目计划分割成较小的不可变部分,而不是减少前期文档以及检查和调整每一个小的开发步骤。而且,我们的前端开发人员的工作流程很难管理。有许多次,团队的其他人员都停下来,等待UI修改完成。在其他冲刺中,他们又无事可做,这种让人沮丧的境况导致部分前端开发人员离职。

\\

我们如何改变了航向?

\\

我们从自己的变革中学到了什么?我们哪里违背了康威定律的观点?这如何促进了进一步的提升?下面是我们找到的部分答案:

\\
  • Scrum并不适合所有的团队、所有的情况。那就是为什么我们必须要求人们检查和调整自己的工作流程以满足需要,并鼓励他们了解业务的全局。\\t
  • 所以,我们需要敏捷团队关注端到端的价值流程,而不是仍然面向筒仓的Scrum。而且,我们需要敏捷教练有企业家的跨部门的视野,而不是像Scrum主管那样只专注于一个团队。\\t
  • 我们还认识到,不只是领导者需要一个更趋向于T型的技能集,所有的工程师都需要。在特定领域拥有知识深厚的I型专家挺好,只要他们能够并且愿意涉及其相应技术之外的主题。在理想情况下,将来我们的工程师既对跨部门协作持开放态度,又乐于改进软件质量,而不会等到有了明确的业务需求才那么做。\\t
  • 承担起Bug修复的职责增进了我们对系统性问题的了解。另一方面,在使用一个大型共享数据库的情况下,全心全意地投入到业务领域及相关软件仍然相当困难。为了提升我们的速度和敏捷性,我们越来越迫切地感觉到要减少对业务端和技术端的依赖。\\t
  • 如果不给团队的产品经理充分授权,让他们可以推动产品愿景的实现,那么他们就无法增加价值。我们只有对每个团队充分授权,让他们在整个开发过程中自主地创建、检查及调整他们的特性,而不只是执行来自外部的需求,我们才可以有所作为。\\t
  • 自上而下推动的决策过程无法达到预期的结果。为了鼓励更多的创新,我们也必须支持自下而上的过程。\\t
  • 虽然团队授权是该做的事情,但跨不同团队和部门的沟通以及协作仍然是一个大问题。\\t
  • 只是改革我们的组织设置及创建新的角色是不够的。作为一项分层桥接的跨职能的团队活动,为了建立领导力,我们还必须解决所有管理角色之间的冲突。\

简而言之,我们认识到,我们必须投入更多的精力,以便使用正确的方法构建正确的东西,而不是忙个不停。而且,我们必须加快我们的整体流程,并为此定义清晰的职责。为此,我们设定了新的改进指标。

\\

首先,我们提升了UX和产品管理的重要性。在最高管理层的推动和外部培训师的支持下,我们实现了一个包括用户测试、用户实验室和团队UX工程师在内的UX流程。同时,产品经理承担为我们的客户开发有价值的软件的全部职责。为了减少众所周知的沟通障碍,测试部门成了工程部门的一部分。如图6所示,这形成了一个新的组织设置和工作流程。图7展示了新的团队设置。

\\

e75b4abf50ae353e46b28720dcff6d5c.png

\\

图6:新的组织设置和工作流程

\\

9e616b33fdcd99209338441e0e016a97.png

\\

图7:第二步:新的团队设置

\\

不再坚持“纯粹的”Scrum,团队开始寻找新的敏捷方法。团队改变了自己的组织方式。这是以一系列的团队建设专题讨论会为支撑的。我们通过这些研讨会评估现状,定义可以作为构建基础的基本优势,商定新的规则和价值观。同时,通过运用各种不同的同伴反馈方法,我们培养了开放沟通和相互帮助的文化。

\\

管理团队也关注团队建设。他们在整个业务部门内进行元回顾,定义可以作为构建基础的优势,深入问题和解决方案。一项重要的改进是,我们开始共同合作,创造性地评估相互矛盾的角色,提取出了精益领导力的第一个概念。任务重叠,界限模糊,决策策略让人困惑,对于这种有些混乱的局面,我们如何有效地进行简化?实际上需要什么样的指导?每一种领导角色都增加了什么价值?需要多少角色?那些角色之间的职责如何划分?

\\

为了培养更多自下而上的流程,我们还修改了我们用来管理变更方案的方法。作为其中的一部分,我们开始在那些方案中包含更多的功能专家。我们新增了所谓的变更团队,而不只是执行由高级管理人员定义的策略。该团队的成员来自那些受变更影响最大的团队,他们被赋予了自主权,可以在一个清晰的界限内研究并实现自己的解决方案。这与其他增强所有权的策略是一致的,比如各种社区实践、有关松弛时间或联合黑客马拉松的明确协议。

\\

我们主要关注的是提升人们提出更多思路和解决方案的内在动机,而不是试图通过诸如金钱、奖金等这些由高级管理人员定义的外部动力来激励人们。为了消除这种外部动力,其中一项改革是将薪金的一些动态部分移到了固定部分。由于其中的部分指标不再由上层管理人员定义,所以团队自己设置自己的指标。

\\

同时,我们继续将我们的软件拆分成微服务。在咨询了外部软件架构师之后,我们为了实现那个目标开启了一项重大的重构计划。通过这项计划,我们希望可以获得完整的跨职能团队,通过独立部署缩短上市时间。我们希望创建对特定领域的技术和业务全权负责的团队。

\\

在建立了重构团队并提取了第一个微服务后,项目终止了。高级管理人员的整体参与度还是太低,而且作为一个整体进行重构太大太冒险。由于重构计划停止了,所以周期时间仍然很长,创新成为意外而不是惯例。我们的技术债务仍在增加。这反映出,我们的组织结构仍然妨碍改进。我们把大量的时间浪费在了权限讨论上,而不是提升软件质量或者实现新的技术。为了有效地实现微服务,我们需要给产品团队更大的自主权,让他们选择自己的工具,并全权负责包括部署在内的整个软件生命周期。即使在上述大规模的重构计划终止以后,工程师们还是深信,将共享的遗留代码库迁移到更小的服务不可避免。现在,我们的新做法是,只要有新需求添加到相应的代码区域就删除旧有的业务逻辑部分。

\\

作为改进工作的一部分,团队改变了维护内部部署和测试框架的习惯做法。他们停下来开发自己的解决方案,致力于保持现有工具的稳定性。我们一致同意使用一种新的策略,让我们可以使用开源的部署和测试工具部署每一个新的服务,而不是使用旧有的内部工具。这样,产品团队变得日益强大,对有效地改进东西越来越有信心,他们开始推动创新。

\\

发现新大陆

\\

所有这些指标把我们带到了哪里?什么有了实际的提升,什么保持不变,而什么变得更糟?以下是对我们2015年及2016年前2个季度一直忙于开展的工作的总结。

\\

在技术方面,我们继续向着独立的微服务发展。同时,我们改善了基础设施部门和工程部门之间的合作。基础设施部门的人员开始向工程师们的实际需求看齐,而不是或多或少地独立创建和维护他们自己的服务,忽视了依赖。

\\

逐渐地,部分产品团队承担起了为新服务创建所需基础设施以及运维新服务的职责。因此,团队现在可以从操作系统层面开始加入自己的技术。这是逐步建立DevOps文化的其中一个先决条件。

\\

我们还实现了工程工具的现代化。工程师现在可以自由选择自己的工作站或者笔记本电脑,而不是一个中央虚拟机。一方面,他们有更大的自由来创建自己的环境和工具,另一方面,他们必须增强自己的主人翁意识。此外,我们使用GitHub开辟了新的软件开发路径。

\\

在组织设置方面,我们继续向着精益领导力发展。如图8所示,我们删除了ScrumMaster的角色。对于这个角色,我们认为其作为敏捷催化剂的功能已经完成,团队已经足够成熟,可以实现自组织。我们一举建立了一个精益-敏捷教练(LAC)池,可以提供支持团队及管理者的新途径。

\\

f3f110ad6da2ebd124f5663572cd9b3c.png

\\

图8:现在的开发团队设置

\\

我们还加大力度,使重要的信息尽可能地透明。可视化管理系统的问题变得愈加重要。产品经理引入了所谓的“墙”来展示有关当前业务选项和即将到来的变更的信息。图9展示了设在办公室中央开放空间里的这块板子的最新版本。通过这种方式,我们增加了业务流程的透明度,从通过评估和选择创建业务选项,到开发、验证和完成——这块看板增强了人们的求知欲,促进了沟通交流。

\\

1ae153c72c1d91409a1775aa15144438.png

\\

图9:“墙”

\\

谈及透明度,整个公司都开始每个季度会面,分享团队在最近一个季度里完成的工作以及他们希望在下一个季度里达到什么目标。以新方法为基础,我们还构建了更为透明的变更方案。变更团队的实施方案会同各方面的利益干系人进行公开讨论,例如,使用鱼缸讨论法的形式。这种方法更容易让那些受影响的人参与进来,了解工作进展,促进总体投入。这还有助于直接传递变更的内容和原因,让人们对变更的实现方法有一个统一的认识。变更的能量来自于面对面的交流和协商一致的行动,而不是官方公告、正式的启动会议或者专家的总体规划。

\\

我们提供了一系列的领导力培训,例如,关于如何领导一个人员来自各个领域的自组织团队。第一次,来自不同领域的领导者,如产品经理、团队负责人、董事和HR,都致力于就未来如何管理公司达成共识。为了有效地支持自组织,需要什么?就能力和实践来说,这意味着什么?共同探讨精益和敏捷领导力的原则,他们还增进了彼此之间的了解,增加了信任和相互理解。

\\

所有这些方案帮我们减少了筒仓逻辑,培养了专注于整个价值流的跨团队协作。与此同时,整个工程部门还形成了一种事后反思和回顾的新文化。实际问题和重大事宜现在都是直接沟通,而不是背后指责和议论。不管是在系统层面,还是在个人层面,提供和接收诚实的反馈都是非常有价值的。

\\

我们现在的状况

\\

所有这些变革对我们的业务有什么影响?我们的变革之旅对我们现如今的自我组织方式有什么意义?再次对照康威定律,图10和11展示了我们现在的组织结构。

\\

3a2d7b3b92ef8118f43b9161cfa7cc68.png

\\

图10:2016年eSailors的组织方式

\\

a1037f7b79bd36bef05b2fea71f7ab80.png

\\

图11:2016年eSailors的组织结构

\\

在摆脱了装配线流程后,现在,跨职能产品团队成为我们关注的焦点。它们是我们保持高效、作出所有重要决策以及推动任何必要变革的引擎。产品团队的重点工作不再是根据特定的规范开发软件产品,然后交付给或多或少不连通的部门,相反,他们既可以决定实现什么,又可以决定如何实现。其他部门提供支持服务,比如数据、基础设施或者咨询。每个团队都可以独立地部署和监控他们的软件。不过,他们通常会合理利用运维部门提供的工具。类似地,团队可以自己做些用户研究,但会有一个用户实验室为他们提供支持。

\\

图12说明了现如今的产品团队如何涵盖了整个开发周期。该循环始于识别客户需求和痛点。基于在这个发现阶段了解到的内容,我们可以发现商机,并使用一个特定的画布对它们进行评估。接下来是设计原型以及用户测试,从中我们可以了解到实现正确的功能所需要的一切信息。经过一定数量的循环后,这些功能就不会发布到生产环境里了,然后我们会进行监控,并通过A/B测试进行微调。

\\

dbc9b4cbb3b6938cb3557172d9c1a37a.png

\\

图12:eSailors的开发周期

\\

我们的技术也发生了极大的变化。从原先一个很小的技术集和占主导地位的“大泥球”,我们设法减少了后者,并增加了前者的多样性。我们不再什么系统都仅使用一种数据库解决方案(Oracle),而是在生产环境中使用多种不同的数据库(Oracle、Mongo、Redis、Elasticsearch、Cassandra)。我们不再仅仅关注一门编程语言(Java),我们现在使用不同的语言(Java、Scala、Go、Swift)。还有其他新的工具和库,例如,docker、ansible、vagrant、angularJs、consul或openstack。每个团队都有特定的功能领域。他们现在有权自己选择最适合团队需求的技术栈,为他们的特性构建解耦合的微服务。通过选择恰当的工具,而不是实现某项共享技术的变通方案,将新特性交付到生产环境变得越来越快越来越简单。这是可能的,因为团队的工程师现在可以专注于自己的部分,并对自己所开发的服务的全生命周期负责。如果不是对技术栈全权负责,如果需要向其他部门进行彻底地交接,那么这种技术的异构性是不可能的。

\\

我们还没有完成我们的微服务架构,但是我们使用微服务实现了所有的特性。我们还在继续逐步地改进我们的架构。发布新服务的提前期也有了显著的改善。现在,新服务几分钟内就可以构建、标记、测试和部署到生产环境。有时候,从构思到完全实现只需要一天,而不是几周。

\\

虽然我们取得了许多成果,但是我们仍然面临着巨大的挑战。一方面是技术挑战,比如我们的架构的复杂性、我们接下来的微服务旅程或者保证设施随时可用的困难。同时,我们面临着组织和业务上的挑战。在通向始终如一的精益敏捷企业的道路上,我们还面临着一项挑战,就是团队没有真正的得失责任。即使一个产品团队成功地使其价值流的所有干系人都参与进来,其工作的整体成本和回报对这些人来说也是不透明的。

\\

完备的企业产品管理职责是当前困扰我们的一个问题。产品经理关注收益(收入、注册量……),而成本本身(人员编制、工资、硬件、外部服务、培训……)是工程成本中心的一部分。内部基础设施的成本或者产品的营销成本根本没有体现到产品团队上。

\\

为了追踪行动的成本和收益,我们在数据及KPI可视化方面取得了很大的进步。但是,因为无法将实现成本、基础设施的成本和工作映射到这类行动上,所以通常很难评价一项实现是否增加了任何价值。

\\

跨团队交流和整个系统的公共视图是困扰我们的另一个问题。现在,我们还不是很清楚应该如何改进我们的端到端工作流。目前,我们即将研究如何使用我们的“墙”(见图9)作为一种方法来更好地管理我们的价值流——即所谓的看板“飞行高度(flight level)”34。通过扩大业务视角,我们可以从一步一步的价值创造流程中获得新的视角……而且,为了统一监控和积极控制整个公司里正在发生的事情,我们考虑将所有领域的代表都包含进来。我们坚信,这可以提升我们的能力,让我们可以更好地区分选项,改善提前期,通过较小的努力提供更大的价值。

\\

参考资料

\\
  1. “How Do Committees Invent?” Melvin E. Conway\\t
  2. “分析师瞭望:Water-Scrum-fall是敏捷的现状”Dave West\\t
  3. “领导自组织团队” Siegfried Kaltenecker(免费下载)\\t
  4. “看板的飞行高度” Klaus Leopold\

关于作者

\\

c53d33cb15efacf369beb9945c079e87.pngMichael Gruczel是esailors移动App团队的团队负责人。在实际的工作中,他像仆人一样工作,但有时候又是一名具有破坏性的领导者。他曾经做过咨询顾问,为德语版的Java Magazin和jaxenter写过一些技术文章。感兴趣的读者可以通过linkedin、twitter(@mgruc)联系他,或者通过他的github个人资料了解他。

\\

f46e7b3757aada9ab1bc1d76cc1c65c2.jpgSigi Kaltenecker是Loop Consultancy的联合常务董事,专注于精益和敏捷变革。他已参与了多家国际性公司的改革,包括Alcatel、bwin.party、eSailors、Kaba、ImmoScout24、Magna、RWE、Swiss Federal Railways或Thales Group。Sigi是《领导自组织团队》、《看板改革领导力:创建持续改进文化》(Wiley 2015))的作者,并在“Peer Feedback Loops”上发表了一系列的文章。感兴趣的读者可以通过电子邮件(siegfried.kaltenecker@loop-beratung.at)联系他。

\\

03830b2e4bdcbdce7c4be42102fa329f.jpgHans Gruber是eSailors汉堡公司的工程负责人和董事总经理。他有很强的工程背景,在类似Tele2和bwin.party这样的国际性企业里逐步建立起自己的专长。他致力于通过采用精益和敏捷实践来改善团队,因为他坚信,技术和产品团队可以做到精益求精,并借此提供卓越的客户价值。感兴趣的读者可以通过linkedin联系他。

\\

查看英文原文:Agile Sailors - A Journey from a Monolithic Approach to Microservices

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQLCMD的介绍

SQLCMD的介绍 原文:SQLCMD的介绍文章转载自:http://blog.sina.com.cn/s/blog_3eec0ced0100mhm2.html最近经常用到超过80M *.sql文件的导入问题。上网找了一下,发现超过80M的文件是不能在查询分析器中执行的。找了些解决方案,个人感觉最简单的…

怎样下载C/C++的免费、开源且跨平台IDE——Code::Blocks

进入Code::Blocks的官网,官网地址为:http://www.codeblocks.org/home。进入后如下图所示: 点击“Home”菜单,跳转到IDE的下载界面: 有几种模式可供选择,我选择的第一种,Download the binary rel…

Logistic回归 python实现

Logistic回归 算法优缺点: 1.计算代价不高,易于理解和实现2.容易欠拟合,分类精度可能不高3.适用数据类型:数值型和标称型 算法思想: 其实就我的理解来说,logistic回归实际上就是加了个sigmoid函数的线性回归…

python 定时自动爬取_python实现scrapy爬虫每天定时抓取数据的示例代码

1. 前言。1.1. 需求背景。每天抓取的是同一份商品的数据,用来做趋势分析。要求每天都需要抓一份,也仅限抓取一份数据。但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量有关,一般情…

博客园win8客户端开发记录5-app设置 登录 回复评论

这段时间完成了博客园cnblogs登录,注销和设置的相关功能 ,进入软件, 打开win8的charm setting 选择设置就是当前软件的设置选项了, 感觉这有点山寨mac os x系统(所有软件包括当前系统使用统一的设置)。 扯远…

简单工厂模式,工厂方法模式,抽象工厂模式,spring的狂想

菜鸟D在项目中遇见一个比较纠结的高耦合,所以就想办法来解耦。情况是这样的:系统通过用户选择treeview控件的节点判断调用不同的处理,这些处理中某些东西又是类似的。同事的建议是采用简单工厂,耦合就耦合吧,反正treev…

如何使用CSS实现居中

前言: 这一篇主要是翻译 《how-to-center-anything-with-css》这一篇文章的主要内容,再加上自己的一些概括理解;主要问题是解决垂直居中的问题。我们知道实现水平居中的方式很多种,比如: text-align:center; margin:0 …

java布局_运用 BoxLayout 进行 Swing 控件布局

引言在用户使用 Java Swing 进行用户界面开发过程中,会碰到如何对 Java Swing 的控件进行布局的问题。Swing 的控件放置在容器 (Container) 中,容器就是能够容纳控件或者其它容器的类,容器的具体例子有 Frame、Panel 等等。容器需要定义一个布…

java链表实现_链表的原理及java实现

一:单向链表基本介绍链表是一种数据结构,和数组同级。比如,Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。下面对单向链表…

xss challenge 解题思路(1-3)

challenge1: 用很基本的方法即可&#xff0c;截图如下&#xff1a; 提交后成功弹窗&#xff0c;完成。 challenge2 这次我们发现我们输入的内容被放入value”“ 中&#xff0c;所以需要将前面的结构闭合&#xff0c;构造如下&#xff1a; "><script>alert(docume…

宾得准饼干广角镜头DA15

DA15的挂机效果图&#xff0c;感觉还是超级的小&#xff0c;是最小的广角镜头了&#xff1a; 主要特点1. 超广视角当安装在宾得数码单反相机上时&#xff0c;这款全新的镜头提供相当于35mm胶片规格的约23mm画面视角&#xff0c;可使拍摄者拍摄出独特的诱人影像和超广角镜头独有…

java slf4j_SLF4J 使用手册

原文链接 译者&#xff1a;zivyuJava的简单日志门面( Simple Logging Facade for Java SLF4J)作为一个简单的门面或抽象&#xff0c;用来服务于各种各样的日志框架&#xff0c;比如java.util.logging、logback和log4j。SLF4J允许最终用户在部署时集成自己想要的日志框架。需要…

[译]Java 垃圾回收介绍

说明&#xff1a;这篇文章来翻译来自于Javapapers 的Java Garbage Collection Introduction 在Java中&#xff0c;对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的。和C语言不一样的是&#xff0c;开发中不需要在Java中写垃圾回收代码。这也是使Java更加流行而且帮…

打印三角形

直角三角形 #include<iostream> using namespace std; int main() { int i,j; for(i1;i<10;i) {for(j1;j<i;j) cout<<"*"; cout<<endl; } } ———————————————————————————…

Linux基础入门学习笔记之二

第三节 用户及文件权限管理 Linux用户管理 Linux是可以实现多用户登录的操作系统 查看用户who命令用于查看用户 shiyanlou是当前登录用户的用户名 pts/0中pts表示伪终端&#xff0c;后面的数字表示伪终端的序号。 后面是当前伪终端启动时间 创建用户创建用户需要root权限&#…

这几天有django和python做了一个多用户博客系统(可选择模板) 没完成,先分享下...

这个TBlog已经全新改版了&#xff0c;更名为UUBlog 新版地址&#xff1a; 用Python和Django实现多用户博客系统——UUBlog 断断续续2周时间吧&#xff0c;用django做了一个多用户博客系统&#xff0c;现在还没有做完&#xff0c;做分享下,以后等完善了再慢慢说 做的时候房展了博…

MySQL数据高级查询之连接查询、联合查询、子查询

2019独角兽企业重金招聘Python工程师标准>>> 一、连接查询 连接查询: 将多张表(>2)进行记录的连接(按照某个指定的条件进行数据拼接)。 连接查询的意义: 在用户查看数据的时候,需要显示的数据来自多张表. 连接查询: join, 使用方式: 左表 join 右表&#xff1b;左…

Oracle11g解锁报错SP2-0306-选项无效

普通用户登录isqlplus: (一)在浏览器中输入URL &#xff08;http://localhost:5560/isqlplus&#xff09;。显示登录界面 这里只能用普通用户进行登录&#xff0c;因为要用sys登录&#xff0c;必须用sys的DBA身份登录。所以用普通用户SCOTT&#xff0c;但是还未解锁 问题:SP2-0…

Chrome浏览器无法观看视频,一直提示“adobe flash player 已过期” ?

很多新用户在安装了Chrome浏览器或者更新过的的时候&#xff0c;经常提示“ adobe flash player 已过期”的问题&#xff0c;反复提示&#xff0c;导致无法观看视频。于是从网上也找了很多办法都没有解决。这里给大家提供一个最完美的解决方案。经亲自测试&#xff0c;完美解决…

关于JVM的垃圾回收GC的一些记录

目录 一、JVM内存区域划分 二、从一个基本问题开始引入垃圾回收 三、GC作用的区域 三、如何确定一个对象是否可以被当成垃圾进行回收 &#xff08;1&#xff09;引用计数法 &#xff08;2&#xff09;可达性分析算法 &#xff08;3&#xff09;引用的类型 &#xff08;3…