一、概念解释
1. 敏捷开发方法与 Scrum 方法
a.敏捷是一种强调轻量的过程方法论,它强调拥抱变化而不是与之对抗,通过有效
的沟通发挥群体的智慧。敏捷方法采用迭代/增量开发的过程模型。敏捷宣言是:
(1) 个体和交互高于流程和工具;
(2) 工作的软件高于详尽的文档;
(3) 客户合作高于合同谈判;
(4) 响应变化高于遵循计划。
虽然右边的也有价值,但是认为左边的更有价值。
b.Scrum(Schwaber 和 Beedle)是管理两个披萨规模(4-9 人)的软件开发团队的方法,
它高频率的短会——每天相同的时间地点进行 15 分钟——给了它这个名字。每日的
Scrum 的好处就是,让大家明白团队里的每个成员都在干什么,团队能够确认工作从而
帮助其他人有更快的发展。
自我管理的团队 Scrum 模式,该模式需要一个成员充分产品负责人的角色,一个充
当客户的角色,以及一个来缓冲团队和外部琐事的 Scrum 主管。团队成员所充当的角色
随着时间在变换。
2. 基于计划-文档开发方法(Plan-and-Document based Development)
软件的开发过程或生命周期依赖于预先仔细的规划、广泛而详尽的文档和精心的管
理使软件开发前景更加清晰。在编程之前,项目经理制定计划;在每个计划阶段,书写
详细的文档;根据计划制定项目的进度;项目的变更必须反应在文档中,可能的话在计
划中体现。著名的案例像瀑布模型、螺旋模型和 RUP 统一开发,这些都是根据基于计
划-文档开发方法实现的开发过程。
3. DRY (Don’t Repeat Yourself) 无重复代码
系统中的每一个知识(功能或特性)必须有单一的、无二义和明确的表示。敬告大
家不要重复代码来达到复用的目的,一个规则只实现一次是面向对象编程中的基本准则,
旨在软件开发中减少重复的信息。
4.MVC(软件作为服务的开发框架)
MVC 全名是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)
的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,
将业务逻辑聚集到一个部件中,在改进和个性化定制界面及用户交互的同时,不需要重
新编写业务逻辑。MVC 被独特的发展起来用于映射传统的输入、处理和输出功能在一
个逻辑的图形化用户界面的结构中。
Model(模型):模型与应用程序操作的数据有关,如何存储、操作以及改变数据。
View(视图):呈现给用户的视图包含用户与之进行交互的模型信息。
Controller(控制器):控制器是传递两个方向交互的中介。当用户与视图进行互动,
一个特殊的控制器对此作出行动以回应用户的调用行为。
5. SMART 用户故事
用户故事,一个从人机交互(HCI)社区借来的方法,使非技术人员更易于提出功能需
求。SMART 缩写涵盖了用户故事令人满意的功能,判断一个用户故事好坏的标准:
(1)确定性(Specific):功能的描述具体,不模糊;
(2)可评估(Measurable):每一个合理的输入都有确定的预期结果;
(3)可实现(Achievable):一个敏捷周期应当能实现一个用户故事,否则该故事的难度太
大, 应当进行分割;
(4)相关性(Relevant):一个故事必须对一个或者多个涉众有商业价值;
(5)时间限制(Timeboxed):如果超出时间预算,需要停止开发对应的故事,此时要么放
弃,并将用户故事分割为更小的,要么重新评估,重新规划时间,安排剩下的时间和任务。
6. TDD AND 红-绿-重构
a. TDD(Test-driven development)测试驱动开发,是敏捷开发中的一项核心实践和技
术,也是一种设计方法论。TDD 的原理是在开发功能代码之前,先编写单元测试用例代
码,测试代码确定需要编写什么产品代码。
b. 测试驱动开发(TDD)循环又被称为红-绿-重构:
(1)在你写任何新的代码前,写一个这段代码行为应当有的在某个方面的测试。
由于被测试的代码还不存在,写下测试迫使你思考想要的代码如何表现,以及与可能存
在的协作者如何交互。我们把这种方法叫作“检测你想要的代码”。
(2)红色步骤:运行测试,并确认它失败了,因为你还没有实现能让它通过测试的
代码。
(3)绿色步骤:写出能使这个测试通过但不损坏其他已有的测试的尽可能简单的
代码。
(4)重构步骤:寻找重构代码或测试的机会,改变代码的结构来消除冗余、重复或
其他可能由添加新代码而引起的丑陋现象。测试能保证重构不会产生错误。
(5)重复以上步骤直到所有必须通过情景步骤的行为都完成。
7. FIRST 测试
创建一个好的测试有以下五个原则,首字母缩写为 FIRST:
(1)Fast(快速):它应该能简单和快速地运行与当前的编码任务相关的测试用例
来避免妨碍你连贯的思路。
(2)Independent(独立):任何测试都不应依赖于由别的测试引出的先决条件,这
样我们才能优先运行覆盖最近改动代码的测试子集。
(3)Repeatable(可重复):测试行为应当不依赖于外部因素。
(4)Self-checking(自校验):每一个测试都应该是能够自己决定测试是通过还是失
败,不依赖于人工来检查它的输出。
(5)Timely(及时):测试应该在代码被测试的时候创建或更新。
8. 代码味道及类内方法 SOFA 方法
可以通过两种方法确定代码是否是“漂亮”得:定量的软件度量和定性的代码味道。
代码味道,即不易被度量的描述的源代码的结构特征,和真实的气味一样,代码味道能
将我们的注意力吸引到可能有问题的地方。
SOFA 代表四种特殊的味道
1) 保持简短(short),以便能迅速获取主要目的。
a) 在不同的地方有一些完全相同的代码
b) 提取方法将多余的代码装入,以便重复的地方都能调用
2) 只做一(one)件事,以便测试能集中于彻底检查这一件事。
a) 对一个类或方法的细小改动会波及到其他类或方法。
b) 通过移动方法和字段来把所有的数据集中到一个地方。
3) 输入少量(few)的参数,以便非常重要的参数值组合都能被测试到。
a) 多个数据项经常作为参数一起传递
b) 使用提取类或保存整个对象来创建一个类,将数据聚集,并传递该类的实例。
4) 维持一个固定级别的抽象(abstraction),以便它不会在如何做和怎么做之间来回跳转。
a) 一个类对另一个类实现的信息了解太多。
b) 如果这些方法确实在别处需要,那么可以移动方法或字段;如果两个类之间有重叠,
那么就使用提取方法,或使用委托来隐藏实现细节。
9. 类间关系的 SOLID 原则
1) 单一责任原则。 一个类有且只有一个修改的理由
a) 庞大的类,方法缺乏内聚性 b) 提取类,移动方法
2) 开闭原则。对拓展保持开放,对修改保持封闭
a) case 选择语句
b) 使用策略或模板方法,可能结合其他抽象工厂模式;使用装饰器来避免子类数量
爆炸。
3) 里氏替换原则。替换一个类的子类应该保持正确的程序行为。
a) 拒绝继承,子类破坏性地覆盖一个继承的方法。b) 用委托来代替继承。
4) 依赖注入原则。实现在运行时可能会改变的协同类应该依赖一个中间状态的注入的
依赖。
a) 单元测试需要特别设计的桩来创建嫁接;构造器硬编码到另一个构造器的调用,
而不是允许运行时决定使用哪个其他的类。
b) 注入一个依赖到一个共享的接口,以分离类;根据需要使用适配器模式、外观模
式、或者代理器模式来使跨变量的接口统一。
5) 迪米特原则。仅和朋友交谈,把朋友的朋友当陌生人。
a) 不合适的亲密 b) 委托行为和调用委托方法。
10.持续集成及开发
持续集成是对部署的代码提高保障的一个关键技术,其中的每一个改变都会推送到
代码库中,引发一个集成测试集合来确保任何事都不会垮掉。持续集成通常被整合到一
个全面的开发过程中,而不是简单被动地进行测试。
CI 包括在部署之前运行一组集成测试,这通常比一个单独的开发者自己进行的集成
更广泛;CI 高度依赖自动化,工作流程通过当提交被推送到一个特定的代码库或者分支
时,自动触发 CI 进行测试。
三、设计题
1. 祖先类从低到高排序为:Integer < Numeric < Object < BasicObject
o = Integer
begin
puts o
end while ((o=o.superclass) != nil)
2.
def palindrome?(string)
string.downcase!
format_str = ""
for i in 0..string.size - 1
c = string[i].to_s
if c >= "a" && c <= "z" || c >= "0" && c <= "9"
format_str += c
end
end
puts format_str
return format_str.reverse == format_st
end
x-y
x*y
x+y
#vim calculator_test.rb
require ‘MiniTest/autorun’
require ‘./calculator.rb’
class TestCalculator
能够被分配用于处理该请求。为了适用大规模 SaaS 应用,只需要水平扩展,增加服务器处
理高负载请求即可。
3)持久层不容易扩展。持久层不能简单的通过拷贝多个数据库进行扩展,因为这样可能会
导致数据不一致性问题,同一个项在不同的数据库中值不同。上图显示了主从方法,是在数
据库中读取比写入更频繁的时候使用的。任何从机都可以执行读取,只有主机才能执行写入,
然后主机使用写入的结果尽可能更快地更新从机。这种技术只是延缓了扩展性问题的出现,
而无法从根本上解决这个问题。
3.
1)SaaS 软件遵循客户端-服务器交互模式,三层无共享架构模式以及 MVC 三层架构模式。
(1)传统软件需要将软件安装在使用者的电脑上,在部署时,客户需要考虑硬件等资源以及
操作系统的兼容性。而 SaaS 通过 Internet 提供软件及服务,厂商将应用软件统一部署在自
己的服务器上;(2)SaaS 以服务为核心,按需定制;传统软件一般是直接获取软件许可。
(3)Saas 强调扩展能力和弹性服务,需要云计算的支持,支持按需交付进行扩展;传统软件
一次性购买所有服务器和计算资源进行开发。(4)传统软件需要有自己的运维团队,SaaS 软
件供应商会为用户提供专业的运维。(5)传统软件更新周期长,SaaS 通过互联网随时更新。
2)SaaS 应用遵循客户端服务器模式。在这个模式中客户端只负责发送请求,服务器处理请
求并反馈信息给客户端。对于 P2P 点对点应用,所有的组件都扮演着客户端和服务端的双
重角色,缺乏很好的扩展和负载能力,因此这种类型的软件不适合做成 SaaS。
对安全性或者隐私性要求很高的软件,比如企业的核心应用不适合做成 SaaS。传统的软
件是安装在用户自己的服务器下的,相关的数据可控;而 SaaS 的数据是存放在厂商服务器
上的,数据的隐私性以及安全性都将受到较大的考验,很多核心应用不希望核心数据由第三
方负责。
对性能以及实时性相应要求较高的。例如大数据流量的应用,SaaS 应用远程的特性使得
网络瓶颈对此类应用程序的影响特别严重。性能也会根据用户的行为、供应商网络以及根据
快速增长或者临时峰值的动态调节能力而有很大的不同。
4. (1)ajax 是一种异步传输方式,优点是能够动态获取数据,在及时性方面比较好。缺点
是不能够很好的利用缓存,效率不够高;获取数据频繁,因此如果数据源有限制 IP 访问次
数就会出现问题;可扩展性较差,整个页面每个表单设计一个获取数据源的 Ajax,当数据源
较多时,就会出现负载问题。
(2)传统 Rails 使用数据离线预取的方式。优点是用户访问速度快,能够很好的利用缓存,
不存在 IP 访问受限问题,可扩展性好,只需要增加新的数据源获取即可。 缺点是及时性差,
不能动态更新数据。
5.
#Creating a new MyName
#0
#y
6.
#Hello there, Dave!
7. #1 #0
8. #[2] #[2, 3, 4, 5]
9. # 你好 朋友!
# 再见 朋友. 快回吧!
# 你好 张三!
# 再见 张三. 快回吧!
# 你好 张三!
# 你好 李四!
# 你好 王五!
# 你好 陈六!
# 你好 赵七!
# 再见 张三, 李四, 王五, 陈六, 赵七. 快回吧!
# ...
# ...
10. 局部;实例;类;全局
11.2. users; index 3. Index; user; users.all 4. User 5. User 6. @users; index
12.
(1)has_many…那行底下添加:
validates :name, :email, presence: true
(2)validates 那行改为:
validates :content, presence: { message: "微博内容不能为空" }, length: { maximum: 140 }
13.
(1)编写自动化测试主要有三个好处:
1) 测试能避免回归(regression)问题,即由于某些原因之前能用的功能不能用了;
2) 有测试在,重构(改变实现方式,但功能不变)时更有自信;
3) 测试代码是使用接口来调用实现功能的代码, 因此帮助设计, 并确定代码是如何系
统中其他组件交互。
(2)何时以及如何测试:
1) 首先, 取决于你编写测试的熟练程度。 开发者熟练之后, 更倾向于先编写测试。
2) 其次, 取决于测试代码与应用代码的难度, 你对想实现的功能有多深的认识。
(3)写测试代码的一些建议:
1) 与应用代码相比,如果测试代码特别简短, 倾向于先编写测试;
2) 如果对想实现的功能不是特别清楚,倾向于先编写应用代码,然后再编写测试,并改
进实现方式;
3) 安全是头等大事,保险起见,要为安全相关的功能先编写测试;
4) 只要发现一个问题,就编写一个测试重现这种问题,避免回归,然后再编写应用代码
修正问题;
5) 尽量不为以后可能修改的代码(例如 HTML 结构的细节)编写测试;
6) 重构之前要编写测试代码,集中测试容易出错的代码。我们一般先编写控制器和模型
测试,然后再编写集成测试(测试模型、视图和控制器结合在一起时的行为)。如果应用代
码很容易出错,或者经常变动(视图就是这样),我们就完全不测试。
14.
class Person
@@count=0
def initialize(name, age)
@cust_name=name
@cust_age=age
@@count += 1
end
def self.how_many()
return @@count
end
end
p1=Person.new("John",27)
p2=Person.new("Jane",37)
puts Person.how_many
15. rails generate migration CreateUsers name:string age:int email:string
16. add_column :users, :password, :string
17.如果刚使用过其他的 SaaS 架构,使用 SQLite3 命令行或者 GUI 数据库控制台来手动添
加、改变数据库表或者安装库可能很有诱惑力。但是如果这样做,在将来可能没有一个一致
的方式来重现这些步骤,并且没有办法有条不紊地重新恢复这些变化。此外,由于迁移仅仅
是工程中的一部分文件,可以把它们纳入版本控制,并且查看所有的修改。
18. /photos
Photos#new
POST
Photos#show
/photos/:id/edit
Pthots#update
DELETE
19. validates :password, presence: true, length: { minimum: 6 }
20. has_and_belongs_to_many :courses
has_and_belongs_to_many :users
21. user = User.create(name: "David", age: 20, email:'David@test.com',password:123456)
22. user_David=User. where(:name=>” David”).first
user_David.update_attributes(:password=>"66666")
23. user_last= User.last
if user_last.nil?
puts “user 表中没有数据”
else
user_last.destroy
24. 如果数据保存成功,redirect_to 再次请求同一界面。寻找@client 模型对应的 client_path,
并刷新数据加以展示
如果数据保存失败,render 跳转原本新建 new.html.erb 的 template 输入的资料仍会保存。
25. book edit_book_path(book) :delete new_book_path
26. form_for f.name_field :email f.submit
27. @user.valid? assert_not @user.vaild?
28. assert_template assert_select
42. 功能 1:
用户故事:作为一个电影爱好者,我想要通过日期来浏览电影,以便于我能迅速找到我
感兴趣的电影。
场景 1:用户通过点击网页上的年份如 2008,系统自动将 2008 年的所有电影在网页上
展示出来。
场景 2:用户通过手动输入年份区间如 2001~2008,系统自动将这个区间的电影在网页
上显示出来。
功能 2:
用户故事:作为一个网页浏览者,我想要根据电影发行日期来对电影进行排序,以便于
我能观看最新发行的电影
场景 1:用户通过点击排序栏中的最近更新,系统将会对根据电影发布时间(从最近发
布)来对电影进行排序,并展示在网页中
场景 2: 用户连续点击两次最近更新,系统将会根据电影发布时间(从最早发布)来对
电影排序,并展示在网页中
43.
(2)系统扩展性差,开发困难,各个开发团队最后要整合到一起。
(3)不能灵活进行分布式部署。
44.
单一系统架构:
优点:内部子系统与子系统之间可以共享数据。例如:“评论”子系统可以从“用户”子系
统中获取用户信息。
缺点:(1)子系统之间耦合性太高,所有的子系统属于一个单一的外部 API,其中一个子系
统升级其他子系统都需要升级;
面向服务设计结构:
优点:(1)把系统拆分,所有的子系统是独立分开的使用接口通信,降低了子系统之间的耦
合度。尽管所有的子系统都在书店数据中心的“边界”内,但是它们是像独立的数据中心那
样相互交流的。如果负责评论的子系统希望得到用户的信息,它不能直接访问用户相关的数
据库,它需要去跟用户服务系统申请通过特定的 API 访问。
(2)增加功能时,只需要重新增加子项目,调用其他系统的接口就可以了,功能升级方便;
(3)由于 SOA 的组件性和优良的扩展性,使其可以根据不同的需求进行重组服务和构造。
(4)可以灵活进行分布式部署。
(5)SOA 的关键特性是没有任何服务有权去命名或访问其他服务的数据,而只能通过外部
的 API 来请求数据。
(6)SOA 与传统的软件分层模型并没有对应关系。单一系统架构中每一个更高的层都是在
低一层的基础上建立起来的。然而 SOA 是纵向切分功能,垮了很多层,之后将这些切分连
接起来形成服务。SOA 工作量可能多一点,但是有巨大的可复用性。