外观模式 : 迪米特法则(最少知识原则) : 一个软件实体应当尽可能少的与其他实体发送相互作用. 外观模式核心 : 为子系统提高统一的入口,封装子系统的复杂性,便于客户端调用. 开发中常见的场景 : 频率很高.哪里都会遇到.各种技术和框架中,都有外观模式的使用.如 : JDBC封装后的,commons提供的DBUtils类,Hibernate提供的工具类,Spring JDBC工具类等. 享元模式(FlyWeight) : 场景 : 内存属于稀缺资源,不要随便浪费.如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存. 核心 : 享元模式以共享的方式高效的支持大量细粒度对象的重用. 享元模式能做到共享的关键和区分了内部状态和外部状态. 内部状态 : 可以共享,不会随环境变化而改变. 外部状态 : 不可以共享,会随环境变化而改变. 享元模式实现 : FlyweightFactory享元工厂类 : 创建并管理享元对象,享元池一般设计成键值对. FlyWeight抽象享元类 : 通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态. ConcreteFlyWeight具体享元类 : 为内部状态提供成员变量进行存储. UnsharedConcreteFlyWeight非共享享元类 : 不能被共享的子类可以设计为非共享享元类. 享元模式开发中应用的场景 : 享元模式由于其共享的特性,可以再任何'池'中操作,比如 : 线程池,数据库连接池.String类的设计也是享元模式. 优点 : 极大减少内存中对象的数量; 相同或相似对象内存中只存一份,极大的节约资源,提供系统性能; 外部状态相对独立,不影响内部状态. 缺点 : 模式较复杂,使程序逻辑复杂化; 为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长.用时间换取了空间. 例子 : package com.example.demo.flyweight; /** * 享元类 */ public interface ChessFlyWeight { void setColor(String c); String getColor(); void display(Coordinate c); } class ConcreteChess implements ChessFlyWeight { private String color; public ConcreteChess(String color) { this.color = color; } @Override public void setColor(String c) { this.color = c; } @Override public String getColor() { return color; } @Override public void display(Coordinate coordinate) { System.out.println("棋子颜色 : " + color); System.out.println("棋子位置 : " + coordinate.getX() + "-----" + coordinate.getY()); } } package com.example.demo.flyweight; import java.util.HashMap; import java.util.Map; /** * 享元工厂类 */ public class ChessFlyWeightFactory { // 享元池 private static Map map = new HashMap<>(); public static ChessFlyWeight getChess(String color) { if (map.get(color) != null) { return map.get(color); } else { ChessFlyWeight cfw = new ConcreteChess(color); map.put(color, cfw); return cfw; } } } package com.example.demo.flyweight; /** * 外部状态UnSharedConcreteFlyWeight */ public class Coordinate { private int x,y; public Coordinate(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } package com.example.demo.flyweight; public class Client { public static void main(String[] args) { ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色"); ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色"); System.out.println(chess1); System.out.println(chess2); System.out.println("增加外部状态的处理======"); chess1.display(new Coordinate(10, 10)); chess2.display(new Coordinate(20, 20)); } } 结构型模式汇总 : 代理模式 : 为真实对象提供一个代理,从而控制对真实对象的访问; 适配模式 : 使原本由于接口不兼容不能一起工作的类可以一起工作; 桥接模式 : 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联. 组合模式 : 将对象组合成树状结构以表示"部分和整体"层次结构,使得客户可以统一的调用叶子对象和容器对象. 装饰模式 : 动态的给一个对象添加额外的功能,比继承灵活. 外观模式 : 为子系统提供统一的调用接口,使得子系统更加容易使用. 享元模式 : 运用共享技术有效的实现管理大量细粒度对象,节省内存,提供效率. 创建型模式关注对象的创建过程. 结构型模式关注对象和类的组织. 行为型模式 : 关注系统中对象之间的相互交互,研究系统在运行时对象之间 的相互通信和协作,进一步明确对象的职责,共有11种模式. 行为型模式汇总 : (1) 责任链模式 chain of responsibility (2) 命令模式 command (3) 解释器模式 interpreter (4) 迭代器模式 iterator (5) 中介者模式 mediator (6) 备忘录模式 memento (7) 观察者模式 observer (8) 状态模式 state (9) 策略模式 strategy (10) 模板方法模式 template method (11) 访问者模式 visitor 责任链模式(chain or responsibility) : 定义 : 将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象. 场景 : 打牌时,轮流出牌;接力赛跑;大学中,奖学金审批;公司中,公文审批; 添加新的处理对象 : 由于责任链的创建完成在客户端,因此新增新的具体处理这对原有类库没有任何影响,只需添加新的类,然后再客户端调用时添加即可.符合开闭原则. 链表方式定义责任链 : 非链表方式实现责任链 : 通过集合,数组生成责任链更加实用!实际上,很多项目中,每个具体的Handler并不是开发团队定义的,而是项目上线后由外部单位追加的, 所以使用链表方式订阅COR链就很困难. 开发中常见的场景 : Java中,异常机制就是一种责任链模式.一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch. JavaScript语言中,事件的冒泡和捕获机制.Java语言中,事件的处理采用观察者模式. Servlet开发中,过滤器的链式处理. Struts2中,拦截器的调用也是典型的责任链模式. 例子中 : package com.example.demo.chainOfResp; /** * 封装请假的基本信息 */ public class LeaveRequest { private String empName; private int leaveDays; private String reason; public LeaveRequest(String empName, int leaveDays, String reason) { super(); this.empName = empName; this.leaveDays = leaveDays; this.reason = reason; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public int getLeaveDays() { return leaveDays; } public void setLeaveDays(int leaveDays) { this.leaveDays = leaveDays; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } } package com.example.demo.chainOfResp; /** * 主任 */ public class Director extends Leader { public Director(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 3) { System.out.println("员工 : " + request.getEmpName() + "请假,天数 : " + request.getLeaveDays() + ", 理由 : " + request.getReason()); System.out.println("主任 : " + this.name + ", 审批通过!"); } else { if (this.nextLeader != null) { this.nextLeader.handleRequest(request); } } } } package com.example.demo.chainOfResp; /** * 副总 */ public class ViceGeneralManager extends Leader { public ViceGeneralManager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 60) { System.out.println("员工 : " + request.getEmpName() + "请假,天数 : " + request.getLeaveDays() + ", 理由 : " + request.getReason()); System.out.println("总经理 : " + this.name + ", 审批通过!"); } else { System.out.println("无法申请请假!"); } } } package com.example.demo.chainOfResp; public class GeneralManager extends Leader { public GeneralManager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 30) { System.out.println("员工 : " + request.getEmpName() + "请假,天数 : " + request.getLeaveDays() + ", 理由 : " + request.getReason()); System.out.println("总经理 : " + this.name + ", 审批通过!"); } else { if (this.nextLeader != null) { this.nextLeader.handleRequest(request); } } } } package com.example.demo.chainOfResp; /** * 抽象类 */ public abstract class Leader { protected String name; // 责任链上后继对象 protected Leader nextLeader; public Leader(String name) { this.name = name; } // 设定责任链上的后继对象 public void setNextLeader(Leader nextLeader) { this.nextLeader = nextLeader; } /** * 处理请求的核心的业务方法 */ public abstract void handleRequest(LeaveRequest request); } package com.example.demo.chainOfResp; /** * 经理 */ public class Manager extends Leader { public Manager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 10) { System.out.println("员工 : " + request.getEmpName() + "请假,天数 : " + request.getLeaveDays() + ", 理由 : " + request.getReason()); System.out.println("经理 : " + this.name + ", 审批通过!"); } else { if (this.nextLeader != null) { this.nextLeader.handleRequest(request); } } } } package com.example.demo.chainOfResp; public class Client { public static void main(String[] args) { Leader a = new Director("张三"); Leader b = new Manager("李四"); Leader c = new GeneralManager("王五"); Leader d = new ViceGeneralManager("张强"); // 组织责任链对象的关系 a.setNextLeader(b); b.setNextLeader(c); c.setNextLeader(d); // 开始请假操作 LeaveRequest request = new LeaveRequest("TOM", 30, "回家"); a.handleRequest(request); } } 迭代器模式(iterator) 场景 : 提供一种可以遍历聚合对象的方式.又称为 : 游标cursor模式; 聚合对象 : 存储数据; 迭代器 : 遍历数据 基本案例 : 实现正向遍历的迭代器; 实现逆向遍历的迭代器; 开发中常见的场景 : JDK内置的迭代器(List/Set) 例子 : package com.example.demo.iterator; /** * 自定义的迭代器接口 */ public interface MyIterator { // 将游标指向第一个元素 void first(); // 将游标指向下一个元素 void next(); // 判断是否存在下一个元素 boolean hasNext(); boolean isFirst(); boolean isLast(); // 获取当前游标指向的对象 Object getCurrentObj(); } package com.example.demo.iterator; import java.util.ArrayList; import java.util.List; /** * 自定义的聚合类 */ public class ConcreteMyAggregate { private List list = new ArrayList(); public ConcreteMyAggregate() { super(); } public void addObject(Object obj) { this.list.add(obj); } public void removeObject(Object obj) { this.list.remove(obj); } public List getList() { return list; } public void setList(List list) { this.list = list; } // 获得迭代器 public MyIterator createIterator() { return new ConcreteIterator(); } // 使用内部类订阅迭代器,可以直接使用外部类的属性 private class ConcreteIterator implements MyIterator { // 定义游标用于记录遍历时的位置 private int cursor; @Override public void first() { cursor = 0; } @Override public void next() { if (cursor < list.size()) { cursor++; } } @Override public boolean hasNext() { if (cursor < list.size()) { return true; } return false; } @Override public boolean isFirst() { return cursor == 0 ? true : false; } @Override public boolean isLast() { return cursor == (list.size() - 1) ? true : false; } @Override public Object getCurrentObj() { return list.get(cursor); } } } package com.example.demo.iterator; public class Client { public static void main(String[] args) { ConcreteMyAggregate cma = new ConcreteMyAggregate(); cma.addObject("aa"); cma.addObject("bb"); cma.addObject("cc"); MyIterator iterator = cma.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.getCurrentObj()); iterator.next(); } } } 中介者模式(Mediator) : 核心 : 如果一个系统中对象之间的联系呈现为网状结构,对象之间存在大量多对多关系,将导致关系及其复杂,这些对象称为"同事对象"; 我们可以引入一个中介者对象,使各个同事对象只跟中介者对象打交道,将复杂的网络结构化解为星形结构. 中介者模式的本质 : 解耦多个同事对象之间的交互关系.每个对象都持有中介者对象的引用,只跟中介者对象打交道.我们通过中介者对象统一管理这些交互关系. 开发中常见的场景 : MVC模式(其中的C,控制器就是一个中介者对象.M和V都和他打交道); 窗口游戏程序,窗口软件开发中窗口对象也是一个中介者对象; 图像界面开发GUI中,多个组件之间的交互,可以通过引入一个中介者对象来解决,可以是整体的窗口对象或者DOM对象. Java.lang.reflect.Method#invoke() 例子 : package com.example.demo.mediator; // 中介者 public interface Mediator { void register(String dname, Department d); void command(String dname); } package com.example.demo.mediator; import java.util.HashMap; import java.util.Map; public class President implements Mediator { private Map map = new HashMap<>(); @Override public void register(String dname, Department d) { map.put(dname, d); } @Override public void command(String dname) { map.get(dname); } } package com.example.demo.mediator; // 同事类的接口 public interface Department { // 做本部门的事情 void selfAction(); // 向总经理发出申请 void outAction(); } package com.example.demo.mediator; public class Development implements Department { // 持有中介者的引用 private Mediator m; public Development(Mediator m) { this.m = m; m.register("development", this); } @Override public void selfAction() { System.out.println("汇报工作!没钱了,需要资金支持!"); } @Override public void outAction() { System.out.println("专心科研,开发项目!"); } } package com.example.demo.mediator; public class Finacial implements Department { // 持有中介者(总经理)的引用 private Mediator m; public Finacial(Mediator m) { this.m = m; m.register("finacial", this); } @Override public void selfAction() { System.out.println("汇报工作!没钱了,钱太多了!怎么花?"); } @Override public void outAction() { System.out.println("数钱!"); } } package com.example.demo.mediator; public class Market implements Department { // 持有中介者(总经理)的引用 private Mediator m; public Market(Mediator m) { this.m = m; m.register("market", this); } @Override public void selfAction() { System.out.println("汇报工作!项目承接的进度,需要资金支持!"); } @Override public void outAction() { System.out.println("跑去接项目!"); m.command("finacial"); } } package com.example.demo.mediator; public class Client { public static void main(String[] args) { Mediator m = new President(); Market market = new Market(m); Development development = new Development(m); Finacial finacial = new Finacial(m); market.selfAction(); market.outAction(); } } 命令模式(command) : 介绍 : 命令模式 : 将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作.也称之为 : 动作 Action模式,事务transaction模式; 结构 : Command抽象命令类; ConcreteCommand具体命令类; Invoker调用者/请求者 : 请求的发送者,它通过命令对象来执行请求.一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联.在程序运行时,将调用命令对象的 execute(),间接调用接收者的相关操作. Receiver接收者 : 接收者执行与请求相关的操作,具体实现对请求的业务处理. 未抽象前,实际执行操作内容的对象. Client客户类 : 在客户类中需要创建调用者对象,具体命令类对象,在创建具体命令对象时指定对应的接收者.发送者和接收者之间没有直接关系,都通过命令对象间接调用. 开发中常见的场景 : Struts2,action的整个调用过程中就有命令模式. 数据库事务机制的底层实现; 命令的撤销和恢复. 例子 : package com.example.demo.command; /** * 真正的命令的执行者 */ public class Receiver { public void action() { System.out.println("Receiver.action()"); } } package com.example.demo.command; public interface Command { /** * 这个方法是一个返回结果为空的方法. * 实际项目中,可以根据需求设计多个不同的方法 */ void execute(); } class ConcreteCommand implements Command { // 命令的真正执行者 private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { // 命令真正执行前或后,执行相关的处理! receiver.action(); } } package com.example.demo.command; /** * 调用者/发起者 */ public class Invoke { // 也可以通过容器List容纳很多命令对象,进行批处理.数据库底层的事务管理就是类似的结构! private Command command; public Invoke(Command command) { this.command = command; } // 业务方法,用于调用命令类的方法 public void call() { command.execute(); } } package com.example.demo.command; public class Client { public static void main(String[] args) { Command command = new ConcreteCommand(new Receiver()); Invoke invoke = new Invoke(command); invoke.call(); } } 解释器模式(Interpreter) 介绍 : 是一种不常用的设计模式; 用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的编译器和解释器设计. 当我们需要开发一种新的语言时,可以考虑使用解释器模式. 尽量不要使用解释器模式,后期维护会有很大麻烦.在项目中,可以使用Jruby,Groovy,java的js引擎来替代解释器的作用,弥补java语言的不足. 开发中常见的场景 : EL表达式的处理;正则表达式的解释器;SQL语法的解释器;数学表达式解释器;如现成的工具包 : Math Expression String Parser ,Expression4J等. MESP的网址 : Expression4J的网址 : 访问者模式Visitor : 模式动机 : 对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其 访问方式也有所不同. 定义 : 表示一个作业于某个对象结构中的各元素的操作,它使我们可以在不改变个元素的类的前提下定义作业于这些元素的新操作. 开发中的场景(应用范围非常窄,了解即可) : XML文档解析器设计;编译器的设计;复杂集合对象的处理; 策略模式 : 策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法.并且由客户端觉得调用哪个算法. 本质 : 分离算法,选择实现; 开发中常见的场景 : JAVASE中GUI编程中,布局管理;Spring框架中,Resource接口,资源访问策略;javax.servlet.httpServlet#service(); 例子 : package com.example.demo.strategy; public interface Strategy { public double getPrice(double standardPrice); } package com.example.demo.strategy; public class NewCustomerFewStrategy implements Strategy { @Override public double getPrice(double standardPrice) { System.out.println("不打折,原价!"); return standardPrice; } } package com.example.demo.strategy; public class NewCustomerManyStrategy implements Strategy { @Override public double getPrice(double standardPrice) { System.out.println("打九折!"); return standardPrice*0.9; } } package com.example.demo.strategy; public class OldCustomerManyStrategy implements Strategy { @Override public double getPrice(double standardPrice) { System.out.println("打八折!"); return standardPrice*0.8; } } package com.example.demo.strategy; public class OldCustomerFewStrategy implements Strategy { @Override public double getPrice(double standardPrice) { System.out.println("打八五折!"); return standardPrice*0.85; } } package com.example.demo.strategy; /** * 负责和具体的策略类交互 * 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化 * 如果使用spring的依赖注入功能,换可以通过配置文件,动态的注入不同策略对象,动态的切换不同的算法. */ public class Context { // 当前采用的算法对象 private Strategy strategy; // 可以通过构造器来注入 public Context(Strategy strategy) { this.strategy = strategy; } public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void pringPrice(double s) { System.out.println("您该报价 : " + strategy.getPrice(s)); } } package com.example.demo.strategy; public class Client { public static void main(String[] args) { Strategy s1 = new OldCustomerManyStrategy(); Context context = new Context(s1); context.pringPrice(998); } } 模板方法模式(template method) 模板方法模式介绍 : 模板方法模式是编程中经常用得到模式.它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现.这样,新的子类可以在不改变一个算法结构的前提下重新 定义该算法的某些特定步骤. 核心 : 处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不能确定.因此,我们采用工厂方法模式,将这个节点的代码实现转移给子类完成.既 : 处理步骤父类 中定义好,具体实现延迟到子类中定义. 方法回调(钩子方法) 在好莱坞,当艺人把简历提交给好莱坞的娱乐公司时,所能做的就是等待,整个过程由娱乐公司控制,演员只能被动的服务安排,在需要的时候再由公司安排具体环节的 演出. 在软件开发中,我们可以将call翻译为调用.子类不能调用父类,而通过父类调用子类.这些调用步骤已经在父类中写好了,完全由父类控制整个过程. 什么时候用到模板方法模式 : 实现一个算法时,整体步骤很固定.但是,某些部分易变.易变部分可以抽象出来,供子类实现. 开发中常见的场景 : 非常频繁.各个框架,类库中都有他的影子.比如常见的有 : 数据库访问的封装;Junit单元测试;servlet中关于doGet/doPost方法调用;Hibernate中模板程序;spring中JDBCTemplate,HibernateTemplate等. 例子 : package com.example.demo.templateMethod; public abstract class BankTemplateMethod { // 具体方法 public void takeNumber() { System.out.println("取号排队!"); } // 办理具体的业务 //钩子方法 public abstract void transact(); public void evaluate() { System.out.println("反馈评分"); } // 模板方法,把基本操作组合到一起,子类一般不能重写. public final void process() { this.takeNumber(); // 像个钩子,执行时,挂那个子类的方法就调用哪个. this.transact(); this.evaluate(); } } package com.example.demo.templateMethod; public class client { public static void main(String[] args) { BankTemplateMethod bankTemplateMethod = new DrawMoney(); bankTemplateMethod.process(); System.out.println("----------------------"); // 采用匿名内部类 BankTemplateMethod bankTemplateMethod1 = new BankTemplateMethod() { @Override public void transact() { System.out.println("我要存钱"); } }; bankTemplateMethod1.process(); } } class DrawMoney extends BankTemplateMethod { @Override public void transact() { System.out.println("我要取款!!!"); } } 状态模式(state) 核心 : 用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题; 结构 : Context环境类(环境类中维护一个State对象,他是定义了当前的状态.);State抽象状态类;ConcreteState具体状态类(每一个类封装了一个状态对应的行为); 开发中常见的场景 : 银行系统中账号状态的管理;OA系统中公文状态的管理;酒店系统中,房间状态的管理;线程对象各状态之间的切换. 例子 : package com.example.demo.state; public interface State { void handle(); } package com.example.demo.state; /** * 空闲状态 */ public class FreeState implements State{ @Override public void handle() { System.out.println("房间空闲!!!没人住."); } } package com.example.demo.state; /** * 已预订状态 */ public class BookedState implements State { @Override public void handle() { System.out.println("房间已预订!别人不能定!"); } } package com.example.demo.state; /** * 已入住状态 */ public class CheckedInState implements State { @Override public void handle() { System.out.println("房间已入住!请勿打扰!"); } } package com.example.demo.state; /** * 方法对象 */ public class Context { // 如果是银行系统,这个Context类就是账号.根据金额不同,切换不同的状态! private State state; public void setState(State s) { System.out.println("修改状态!"); state = s; state.handle(); } } package com.example.demo.state; public class Client { public static void main(String[] args) { Context context = new Context(); context.setState(new FreeState()); context.setState(new BookedState()); context.setState(new CheckedInState()); } } 观察者模式(Observer) : 核心 : 观察者模式主要用于1 : N的通知.当一个对象(目标对象(消息发布)Subject或Objservable)的状态变化时,他需要及时告知一系列对象(观察者对象(消息订阅),Observer),令他们做出相应; 通知观察者的方式 : 推 : 每次都会把通知以广播方式发送给所有观察者,所有观察者只能被动接收. 拉 : 观察者只要直到有情况即可.至于什么时候获取内容,获取什么内容,都可以自主决定. 例子 : package com.example.demo.observer; public interface Observer { void update(Subject subject); } package com.example.demo.observer; import java.util.ArrayList; import java.util.List; public class Subject { protected List list = new ArrayList<>(); public void registerObserver(Observer obs) { list.add(obs); } public void removeObserver(Observer obs) { list.remove(obs); } //通知所有的观察者更新状态 public void notifyAllObservers() { for (Observer observer : list) { observer.update(this); } } } package com.example.demo.observer; public class ObserverA implements Observer { // myState需要跟目标对象的state值保存一致! private int myState; @Override public void update(Subject subject) { myState = ((ConcreteSubject)subject).getState(); } public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } } package com.example.demo.observer; public class ConcreteSubject extends Subject { private int state; public int getState() { return state; } public void setState(int state) { this.state = state; // 主题对象(目标对象)值发生了变化,请通知所有的观察者 this.notifyAllObservers(); } } package com.example.demo.observer; public class Client { public static void main(String[] args) { // 目标对象 ConcreteSubject subject = new ConcreteSubject(); // 创建多个观察者 ObserverA obs1 = new ObserverA(); ObserverA obs2 = new ObserverA(); ObserverA obs3 = new ObserverA(); // 将这三个观察者添加到subject对象的观察者队伍中 subject.registerObserver(obs1); subject.registerObserver(obs2); subject.registerObserver(obs3); // 改变subject的状态 subject.setState(3000); // 我们看看,观察者的状态是不是也发生了变化 System.out.println(obs1.getMyState()); System.out.println(obs2.getMyState()); System.out.println(obs3.getMyState()); System.out.println("------------------"); // 改变subject的状态 subject.setState(30); // 我们看看,观察者的状态是不是也发生了变化 System.out.println(obs1.getMyState()); System.out.println(obs2.getMyState()); System.out.println(obs3.getMyState()); } } JavaSE提供了java.util.Observable和java.util.Observer来实现观察者模式; 例子 : package com.example.demo.observer2; import java.util.Observable; import java.util.Observer; public class ObserverA implements Observer { private int myState; @Override public void update(Observable o, Object arg) { myState = ((ConcreteSubject) o).getState(); } public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } } package com.example.demo.observer2; import java.util.Observable; public class ConcreteSubject extends Observable { private int state; public void set(int a) { // 目标对象的状态发生了改变 state = a; // 表示目标对象已经做了更改 setChanged(); // 通知所有的观察者 notifyObservers(state); } public int getState() { return state; } public void setState(int state) { this.state = state; } } package com.example.demo.observer2; public class Client { public static void main(String[] args) { // 创建目标对象Obserable ConcreteSubject subject = new ConcreteSubject(); // 创建观察者 ObserverA observerA = new ObserverA(); ObserverA observerA1 = new ObserverA(); ObserverA observerA2 = new ObserverA(); // 将上面三个观察者对象添加到目标对象subject的观察者容器中 subject.addObserver(observerA); subject.addObserver(observerA1); subject.addObserver(observerA2); // 改变subject对象的状态 subject.set(3000); System.out.println(observerA.getMyState()); System.out.println(observerA1.getMyState()); System.out.println(observerA2.getMyState()); } } 开发中常见的场景 : 聊天室程序的,服务器转发给所有客户端;网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发;邮件订阅;Servlet中,监听器的实现;Android中,广播机制; JDK的AWT中事件处理模型,基于观察者模式的委派事件模型(Delegation Event Model) 事件源 ----- 目标对象 事件监听器 -----观察者 京东商城中,群发某商品打折信息 备忘录模式(memento) : 核心 : 就是保持某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态. 结构 : 源发器类Originator;备忘录类Memento;负责人类CarTake. 备忘点较多时 : 将备忘录压栈 public class CareTaker { private Memento memento; private Stack stack = new Stack(); } 将多个备忘录对象,序列化和持久化; 开发中常见的应用场景 : 棋类游戏中的,悔棋;普通软件中的,撤销操作;数据库软件中的,事务管理中的,回滚操作;Photoshop软件中的,历史记录 例子 : package com.example.demo.memento; /** * 源发器类 */ public class Emp { private String ename; private int age; private double salary; public Emp(String ename, int age, double salary) { this.ename = ename; this.age = age; this.salary = salary; } // 进行备忘操作,并返回备忘录对象 public EmpMemento memento() { return new EmpMemento(this); } // 进行数据恢复,恢复成制定备忘录对象的值 public void recovery(EmpMemento mmt) { this.ename = mmt.getEname(); this.age = mmt.getAge(); this.salary = mmt.getSalary(); } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } package com.example.demo.memento; /** * 负责人类 * 负责管理备忘录对象 */ public class CareTaker { private EmpMemento empMemento; public EmpMemento getEmpMemento() { return empMemento; } public void setEmpMemento(EmpMemento empMemento) { this.empMemento = empMemento; } } package com.example.demo.memento; /** * 备忘录类 */ public class EmpMemento { private String ename; private int age; private double salary; public EmpMemento(Emp e) { this.ename = e.getEname(); this.age = e.getAge(); this.salary = e.getSalary(); } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } package com.example.demo.memento; public class Client { public static void main(String[] args) { CareTaker taker = new CareTaker(); Emp emp = new Emp("高琪", 18, 500); System.out.println("第一打印创建对象 : " + emp.getEname() + "---" + emp.getAge() + "---" + emp.getSalary()); // 备忘一次 taker.setEmpMemento(emp.memento()); emp.setAge(38); emp.setEname("王五"); emp.setSalary(800); System.out.println("第二次打印创建对象 : " + emp.getEname() + "---" + emp.getAge() + "---" + emp.getSalary()); // 恢复到备忘录对象保存的状态 emp.recovery(taker.getEmpMemento()); System.out.println("第三次打印创建对象 : " + emp.getEname() + "---" + emp.getAge() + "---" + emp.getSalary()); } } 你可能感兴趣的:(设计模式2) VMware虚拟机Ubuntu22.04桥接模式无法联网问题--已解决 Hello_World_222 Ubuntu哪些事儿ubuntu网络 需求:需要虚拟机之间的可以互ping问题:虚拟机默认是NAT模式,由DHCP自动分配IP,结果虚拟机IP不在同一个网段(局域网下);查资料,改为桥接模式,改为桥接模式后可以互ping了。但,又连不上网了,搞了一下午,最后看到有人用手机热点,我也就试了一下,然后就成了,原因是,有的wifi路由器不支持桥接模式 《DAMA数据管理知识体系指南》备考笔记-第一章 数据管理 (4 分)_dama8大模块 2401_84411072 程序员笔记大数据 数据:构成信息的基本材料。信息:数据在特定上下文中的应用。P2数据驱动的定义:依赖事件触发和分析应用以获得有价值的见解。这要求业务领导与技术专家合作,并依据专业规则对数据进行有效管理。P3数据管理的核心原则:P4-51高效数据管理需领导层承担其责任。2数据价值:A作为一个具有独特属性的资产;B可以用经济学术语表达。3数据管理的需求源自业务需求:A涉及质量管理。B需要元数据。C需要规划。D应驱动IT 不同类型的网站选择不同的服务器,那么应该怎么选择服务器呢? 咕噜分发企业签名-APP加固-彭于晏 服务器运维 制作网站。但做一个盈利的网站并不是那么简单。服务器的选择与网站的性质密切相关。不同类型的网站选择不同的服务器。那么什么样的服务器更适合网站呢?1、站群现在,有很多站长都是站长,因为站长是一种可以在短时间内显著提高搜索引擎优化效果的方法。一个站点集群的特点之一是需要多个独立的ip,独立的服务器可以满足这一要求。特别是对于站群的独立服务器,大部分独立IP将达到数百个。2、对外贸易各外贸网站规模大、流量 Python 的元组和列表的区别是什么? 海姐软件测试 职场和发展笔记经验分享面试其他 以下是Python中元组(tuple)和列表(list)的主要区别:1.语法表示:元组使用小括号()来定义,例如(1,2,3);列表使用方括号[]来定义,例如[1,2,3]。2.可变性:列表是可变的,即可以对其元素进行添加、删除、修改操作;而元组是不可变的,一旦创建,其元素的值就不能被修改。3.内存占用:通常情况下,元组的内存占用比列表小,因为元组的不可变性使其在某些情况下更易于优化。4.速度:由 Ubuntu 安装 Node.js 20.x 一个双鱼座的测开 中间件ubuntunode.jslinux 在Ubuntu系统上安装特定版本的Node.js(如Node.js20.x)需要一些额外的步骤,因为Ubuntu的官方软件仓库可能不包含最新版本的Node.js。以下是如何在Ubuntu上安装Node.js20.x的详细步骤:1.更新软件包列表在安装任何新软件包之前,建议先更新您的软件包列表。这可以确保您获得的是最新的软件包信息。sudoaptupdate2.添加NodeSource仓库NodeS DEMF模型赋能多模态图像融合,助力肺癌高效分类 cv君 cv君独家视角AI内幕系列深度学习PET-CT集成分类肺部图像多模态图像融合 目录论文创新点实验设计1.可视化的研究设计2.样本选取和数据处理3.集成分类模型4.实验结果5.可视化结果图表总结可视化知识图谱在肺癌早期筛查中,计算机断层扫描(CT)和正电子发射断层扫描(PET)作为两种关键的影像学手段,分别提供了丰富的解剖结构信息和代谢活动信息。然而,单一模态的影像数据在诊断精准度上往往存在瓶颈,难以全面揭示病变特征。因此,如何将多模态影像数据有机融合,以提升诊断效能,已成为 P2865 [USACO06NOV] Roadblocks G 与最短路的路径可重复的严格次短路 Lqingyyyy 算法c++开发语言 题目大意给出nnn个顶点mmm条长度在111~500050005000的边的图,求图中从1到nnn与最短路的路径可重复的严格次短路。(严格的含义是,一定比最短路要长,不能相等)分析我们先将问题简单化,如何去求一个非严格的次短路呢?设次短路径为{1,a1,a2,...,ak,n}\{1,a_1,a_2,...,a_k,n\}{1,a1,a2,...,ak,n}当ak=ia_k=iak=i时,方案变为 高清下载油管视频到本地 栈不全 技术应用音视频 下载工具并安装:yt-dlp官网地址:GitHub-yt-dlp/yt-dlp:Afeature-richcommand-lineaudio/videodownloaderffmpeg官网地址:DownloadFFmpeg注:记住为其添加环境变量操作命令:该指令表示以720p码率下载VIDEO_URL所包含的视频yt-dlp-f"bestvideo[height=720]+bestaudio/be Python Qt6快速入门-模型视图(ModelView) 视觉与物联智能 Python编程实例ui编程语言pythonpyqt6qt6 模型视图(ModelView)文章目录模型视图(ModelView)1、MVC模式介绍2、Qt的MVC模式类介绍3、视图/模型应用实例3.1UI设计3.2模型3.3逻辑功能实现3.4数据持久化Qt包含一组项目视图类,它们使用模型/视图体系结构来管理数据之间的关系及其呈现给用户的方式。这种体系结构引入的功能分离为开发人员提供了更大的灵活性来自定义项目的表示,并提供了一个标准模型接口以允许广泛的数据源 基于BS结构的旅游网站详细设计与具体代码实现 AI天才研究院 DeepSeekR1&大数据AI人工智能大模型AI大模型企业级应用开发实战计算科学神经计算深度学习神经网络大数据人工智能大型语言模型AIAGILLMJavaPython架构设计AgentRPA 基于BS结构的旅游网站详细设计与具体代码实现1.背景介绍1.1旅游行业的发展现状旅游业作为一个朝阳产业,近年来发展迅猛。随着人们生活水平的不断提高,旅游已经成为大众化的消费方式之一。根据世界旅游组织的数据,2019年全球旅游业总收入达到1.7万亿美元,占全球GDP的3.3%。旅游业的蓬勃发展,为相关行业带来了巨大的商机,也推动了旅游网站的兴起。1.2旅游网站的作用旅游网站作为旅游行业的重要载体,为 (学习总结25)Linux工具:vim 编辑器 和 gcc/g++ 编译器 瞌睡不来 linux编辑器学习vimgcc/g++编译器 Linux工具:vim编辑器和gcc/g++编译器vim编辑器在Linux命令行中执行vimvim命令模式光标操作相关命令文本或字符操作命令撤销操作命令查找操作vim插入模式vim底行模式查找与编写操作界面操作文件处理操作vim与shell交互其它操作退出vim一般操作vim可视模式vim替换模式vim简单配置配置文件位置:常用配置选项,用来测试(可以在vim底行模式使用):使用插件gcc/g++ Qt Widgets、QML与Qt Quick 人才程序员 qml基础教程qt开发语言c++c语言uiqml 文章目录前言QMLVSQtQuick概念上的区别模块上的区分QtQuick1.xVSQtQuick2.x1.QtQuick1.x(基于Qt4.x)2.QtQuick2.x(基于Qt5.x)为什么要引入QML/QtQuick?1.战略性发展2.开发效率的提升3.UI与逻辑分离QtWidgetsVSQML/QtQuickQtWidgets的特点:QML/QtQuick的特点:总结前言随着跨平台开发的需 使用yarn创建Nuxt项目报错,改用npm命令 rock——you npmchrome前端 yarndlxnuxi@latestinitwindowshost.nuxtyarnrunv1.22.22errorCouldn'tfindapackage.jsonfilein"/Users/baoge/WebstormProjects/windowshost.nuxt"infoVisithttps://yarnpkg.com/en/docs/cli/runfordocumentationabo stack&&queue的学习 liuyangzhou666 学习 视频:https://www.bilibili.com/video/BV1TG411A7sZ?vd_source=e5ef53bcd02c60bc6cb52e706517483f&p=10&spm_id_from=333.788.videopod.episodes.栈就是一个顶入顶出的东西,对于他只能是对顶部的东西进行操作和读栈的大小,判断栈是否为空#include#includeusingnam 容器链表list的学习 liuyangzhou666 学习c++stllist 视频:https://www.bilibili.com/video/BV1TG411A7sZ?spm_id_from=333.788.videopod.episodes&vd_source=e5ef53bcd02c60bc6cb52e706517483f&p=11#includeusingnamespacestd;#includevoidprintl(listl){list::iteratorit CS架构和BS架构的区别(通俗易懂) 九块六 CS架构BS架构服务器运维 目录一、CS架构1.1.优点:1.2.缺点二、BS架构2.1.优点2.2.缺点三、区别3.1.开发成本3.2.客户端负载3.3.安全性3.4.作用范围CS:Client/Server(客户端/服务器)结构,使用之前需要用户下载安装客户端的操作界面例如:腾讯视频、QQ、微信社交工具、WPS、向日葵、Navicat工具、idea、Xshell等BS:Browser/Server(浏览器/服务器)结构, 推荐开源宝藏:Python UDS(ISO-14229)神器 —— python-udsoncan 房征劲Kendall 推荐开源宝藏:PythonUDS(ISO-14229)神器——python-udsoncan【下载地址】PythonUDSISO-14229实现python-udsoncan`python-udsoncan`是一个用Python3编写的ISO-14229定义的统一诊断服务(UDS)协议的实现。该项目遵循MIT许可,并在GitHub上发布。通过`python-udsoncan`,开发者可以轻松地在P TaskBuilder主界面介绍 Nodejs_home javapython TaskBuilder主界面介绍TaskBuilder的主界面分为如下图所示的7个区域:这7个区域的作用简要介绍如下:2、服务器设置:在此查看和设置任擎服务器的信息。应用系统的代码都是保存在任擎服务器上的,TaskBuilder必须连接任擎服务器才能进行相关操作,且同一时间只能连接一个任擎服务器,默认连接服务器列表中的第一个服务器,可以打开服务器列表选择其他服务器进行切换,切换服务器后,区域4内的 TaskBuilder与VSCode、Eclipse有什么区别? Nodejs_home VisualStudioCode(简称“VSCode”)是Microsoft在2015年4月30日Build开发者大会上正式宣布一个运行于MacOSX、Windows和Linux之上的,针对于编写现代Web和云应用的跨平台源代码编辑器,可在桌面上运行,并且可用于Windows,macOS和Linux。它具有对JavaScript,TypeScript和Node.js的内置支持,并具有丰富的其他语言 机器学习,我们主要学习什么? 悠然的笔记本 机器学习机器学习 机器学习的发展历程机器学习的发展历程,大致分为以下几个阶段:1.起源与早期探索(20世纪40年代-60年代)1949年:Hebb提出了基于神经心理学的学习机制,开启了机器学习的先河1950年代:机器学习的起源与人工智能的探索紧密相连。例如,1956年,达特茅斯会议标志着人工智能的诞生,机器学习作为其重要分支也开始受到关注1960年代:出现了早期的机器学习算法,如1967年诞生的K最近邻算法(KNN R语言 数据导出和导入 csv tsv xls xlsx 仿生bug r语言 【R语言】Excel导出为Excel的xls、xlsx#【-------导出数据--------】write.table(data2,file="train1.xls",sep="\t",row.names=TRUE,col.names=TRUE,quote=TRUE)write.table(data2,file="train2.xlsx",sep="\t",row.names=TRUE,col. deepseek-r1系列模型私有化部署分别需要的最低硬件配置 Sophie'sCookingLab 大模型deepseek DeepSeek-R1系列模型部署所需的最低硬件配置如下:DeepSeek-R1-1.5BCPU:最低4核(推荐多核处理器)内存:8GB+硬盘:3GB+存储空间(模型文件约1.5-2GB)显卡:非必需(纯CPU推理),若GPU加速可选4GB+显存(如GTX1650)适用场景:低资源设备部署(如树莓派、旧款笔记本)、实时文本生成(聊天机器人、简单问答)、嵌入式系统或物联网 单目标追踪——【Transformer】Transformer Tracking zz的大穗禾 论文阅读SOTtransformer深度学习人工智能 目录文章侧重点网络结构上下文增强模块交叉特征增强TransT网络结构可视化结果分析n=1n=2n=3n=4Transformer这个香饽饽怎么能不用来迁移到目标追踪里呢。本篇文章分析TransT。TransformerTracking.文章侧重点这篇文章是利用Transformer设计了一个新的基于注意力的特征融合网络和一个Siamese结构的集成该融合网络的追踪方法TransT。在TransT中 R语言 关联TCGA数据库下载的RNA-SEQ数据和临床信息 胖胖的胖球 生物信息学大数据生物信息学r语言 刚开始学习TCGA数据处理和分析,记下来方便以后查看setwd("E:/MyData/luadRNA-SEQ-20201028")#把工作目录定位到manifest文件所在的位置manifest="gdc_manifest.2020-10-28.txt"x=read.table(manifest,header=T)#header为TRUE表示读取第一行作为变量名表格已经建好了,可以view(x), StarRocks关于ConcurrentModificationException 问题的解决 鸿乃江边鸟 大数据StarRocksSQLstarrocks大数据sql 背景本文基于StarRocks3.1.7目前在基于Starrocks做一些数据分析的操作(主要是做一些简单的查询),同事遇到了一些并发的问题:ontent:2024-11-2707:04:34,048WARN(starrocks-mysql-nio-pool-214933|3593819)[StmtExecutor.execute():643]executeException,sqlSELECTd 【分布式理论13】分布式存储:数据存储难题与解决之道 roman_日积跬步-终至千里 分布式架构分布式 文章目录一、数据存储面临的问题二、RAID磁盘阵列的解决方案1.RAID概述2.RAID使用的技术3.RAID的代表性等级三、分布式存储的新思路1.分布式存储背景与特点2.分布式存储的组成要素一、数据存储面临的问题在单机系统时代,当数据量不断增加、硬盘空间不够时,最简单的解决办法就是扩大磁盘容量。然而,随着数据量的增长,磁盘读写操作的速度成为了限制系统性能的瓶颈。因此,提升存储性能、提高数据的可靠 linux在工作中常用命令 bs_101 工作经验分享linux常用命令 简介记录在日常工作中,常用linux命令查日志篇有cattailgrep等等,这里主要介绍grep的用法1.统计特定内容出现的行数和次数1.查询特定内容出现的行数grep-c"关键词"文件名-c:只显示匹配的行数。2.查询特定内容出现的次数grep-o"关键词"文件名|wc-l-o:只显示匹配的部分,每个匹配项单独成行。wc-l:统计行数,即匹配次数。2.查找上下文内容1.查找包含关键字的行及其上 FPGA比单片机厉害吗? 张巧龙 fpga开发单片机嵌入式硬件 01前言做单片机开发的工程师,一般都会接触FPGA。有读者大概问了这样的问题:FPGA能做什么?比单片机厉害吗?这么说吧,FPGA在某方面也能实现单片机做的事,在某些领域,FPGA远比单片机强的多。当然,FPGA和单片机各有各的特点,在应用上也有一些区别,本文主要说下FPGA厉害的地方。02关于FPGAFPGA(现场可编程门阵列)是一种可编程的硬件设备,通过编程可以定义其内部逻辑电路的结构和功能, 生物信息数据库开发之单细胞数据库scrna db(一) 北京生信课堂 数据库生物信息学r语言python 单细胞数据库构建优质已整合的单细胞数据库背景知识需求分析数据库类型数据库构建过程优质已整合的单细胞数据库如果读者只想获得一个现成的内容丰富的单细胞数据库加入至自己的PC或linux服务器,可以跳过下面的详细理论教程数据库下载链接:点击下载单细胞数据库。包含约800个细胞数据的中小型数据库,维度约为20000x800,部分为作者公司数据,部分为国际数据库数据,包含T-cell,B-cell,NK-c 如何学好网络安全 网络安全(king) 黑客网络安全网络工程师web安全安全网络 “沉寂的深夜,杂乱的小屋,只传出阵阵清脆的键盘敲击声。屏幕上不时闪现出漂亮的3维立体动画的口令提示框….”在很多影视及文学作品中通常都是这样描述黑客及黑客的工作的。在现实生活中,真正黑客的工作是非常枯燥的,可能几天没日没夜的试探只是为了通过那个简陋的WIN2000口令提示框(甚至连框都没有,就是一行简单的字符:Enteryourpassword:)。同样,网络安全专家的工作绝大部分时候也是非常枯燥 html 周华华 html js 1,数组的排列 var arr=[1,4,234,43,52,]; for(var x=0;x<arr.length;x++){ for(var y=x-1;y<arr.length;y++){ if(arr[x]<arr[y]){ & 【Struts2 四】Struts2拦截器 bit1129 struts2拦截器 Struts2框架是基于拦截器实现的,可以对某个Action进行拦截,然后某些逻辑处理,拦截器相当于AOP里面的环绕通知,即在Action方法的执行之前和之后根据需要添加相应的逻辑。事实上,即使struts.xml没有任何关于拦截器的配置,Struts2也会为我们添加一组默认的拦截器,最常见的是,请求参数自动绑定到Action对应的字段上。 Struts2中自定义拦截器的步骤是: make:cc 命令未找到解决方法 daizj linux命令未知make cc 安装rz sz程序时,报下面错误: [root@slave2 src]# make posix cc -O -DPOSIX -DMD=2 rz.c -o rz make: cc:命令未找到 make: *** [posix] 错误 127 系统:centos 6.6 环境:虚拟机 错误原因:系统未安装gcc,这个是由于在安 Oracle之Job应用 周凡杨 oracle job 最近写服务,服务上线后,需要写一个定时执行的SQL脚本,清理并更新数据库表里的数据,应用到了Oracle 的 Job的相关知识。在此总结一下。 一:查看相关job信息 1、相关视图 dba_jobs all_jobs user_jobs dba_jobs_running 包含正在运行 多线程机制 朱辉辉33 多线程 转至http://blog.csdn.net/lj70024/archive/2010/04/06/5455790.aspx 程序、进程和线程: 程序是一段静态的代码,它是应用程序执行的蓝本。进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。线程是比进程更小的单位,一个进程执行过程中可以产生多个线程,每个线程有自身的 web报表工具FineReport使用中遇到的常见报错及解决办法(一) 老A不折腾 web报表finereportjava报表报表工具 FineReport使用中遇到的常见报错及解决办法(一) 这里写点抛砖引玉,希望大家能把自己整理的问题及解决方法晾出来,Mark一下,利人利己。 出现问题先搜一下文档上有没有,再看看度娘有没有,再看看论坛有没有。有报错要看日志。下面简单罗列下常见的问题,大多文档上都有提到的。 1、address pool is full: 含义:地址池满,连接数超过并发数上 mysql rpm安装后没有my.cnf 林鹤霄 没有my.cnf Linux下用rpm包安装的MySQL是不会安装/etc/my.cnf文件的, 至于为什么没有这个文件而MySQL却也能正常启动和作用,在这儿有两个说法, 第一种说法,my.cnf只是MySQL启动时的一个参数文件,可以没有它,这时MySQL会用内置的默认参数启动, 第二种说法,MySQL在启动时自动使用/usr/share/mysql目录下的my-medium.cnf文件,这种说法仅限于r Kindle Fire HDX root并安装谷歌服务框架之后仍无法登陆谷歌账号的问题 aigo root 原文:http://kindlefireforkid.com/how-to-setup-a-google-account-on-amazon-fire-tablet/ Step 4: Run ADB command from your PC On the PC, you need install Amazon Fire ADB driver and instal javascript 中var提升的典型实例 alxw4616 JavaScript // 刚刚在书上看到的一个小问题,很有意思.大家一起思考下吧 myname = 'global'; var fn = function () { console.log(myname); // undefined var myname = 'local'; console.log(myname); // local }; fn() // 上述代码实际上等同于以下代码 m 定时器和获取时间的使用 百合不是茶 时间的转换定时器 定时器:定时创建任务在游戏设计的时候用的比较多 Timer();定时器 TImerTask();Timer的子类 由 Timer 安排为一次执行或重复执行的任务。 定时器类Timer在java.util包中。使用时,先实例化,然后使用实例的schedule(TimerTask task, long delay)方法,设定 JDK1.5 Queue bijian1013 javathreadjava多线程Queue JDK1.5 Queue LinkedList: LinkedList不是同步的。如果多个线程同时访问列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方 http认证原理和https bijian1013 httphttps 一.基础介绍 在URL前加https://前缀表明是用SSL加密的。 你的电脑与服务器之间收发的信息传输将更加安全。 Web服务器启用SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定。 http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后 【Java范型五】范型继承 bit1129 java 定义如下一个抽象的范型类,其中定义了两个范型参数,T1,T2 package com.tom.lang.generics; public abstract class SuperGenerics<T1, T2> { private T1 t1; private T2 t2; public abstract void doIt(T 【Nginx六】nginx.conf常用指令(Directive) bit1129 Directive 1. worker_processes 8; 表示Nginx将启动8个工作者进程,通过ps -ef|grep nginx,会发现有8个Nginx Worker Process在运行 nobody 53879 118449 0 Apr22 ? 00:26:15 nginx: worker process lua 遍历Header头部 ronin47 lua header 遍历 local headers = ngx.req.get_headers() ngx.say("headers begin", "<br/>") ngx.say("Host : ", he java-32.通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小(两数组的差最小)。 bylijinnan java import java.util.Arrays; public class MinSumASumB { /** * Q32.有两个序列a,b,大小都为n,序列元素的值任意整数,无序. * * 要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。 * 例如: * int[] a = {100,99,98,1,2,3 redis 开窍的石头 redis 在redis的redis.conf配置文件中找到# requirepass foobared 把它替换成requirepass 12356789 后边的12356789就是你的密码 打开redis客户端输入config get requirepass 返回 redis 127.0.0.1:6379> config get requirepass 1) "require [JAVA图像与图形]现有的GPU架构支持JAVA语言吗? comsci java语言 无论是opengl还是cuda,都是建立在C语言体系架构基础上的,在未来,图像图形处理业务快速发展,相关领域市场不断扩大的情况下,我们JAVA语言系统怎么从这么庞大,且还在不断扩大的市场上分到一块蛋糕,是值得每个JAVAER认真思考和行动的事情 安装ubuntu14.04登录后花屏了怎么办 cuiyadll ubuntu 这个情况,一般属于显卡驱动问题。 可以先尝试安装显卡的官方闭源驱动。 按键盘三个键:CTRL + ALT + F1 进入终端,输入用户名和密码登录终端: 安装amd的显卡驱动 sudo apt-get install fglrx 安装nvidia显卡驱动 sudo ap SSL 与 数字证书 的基本概念和工作原理 darrenzhu 加密ssl证书密钥签名 SSL 与 数字证书 的基本概念和工作原理 http://www.linuxde.net/2012/03/8301.html SSL握手协议的目的是或最终结果是让客户端和服务器拥有一个共同的密钥,握手协议本身是基于非对称加密机制的,之后就使用共同的密钥基于对称加密机制进行信息交换。 http://www.ibm.com/developerworks/cn/webspher Ubuntu设置ip的步骤 dcj3sjt126com ubuntu 在单位的一台机器完全装了Ubuntu Server,但回家只能在XP上VM一个,装的时候网卡是DHCP的,用ifconfig查了一下ip是192.168.92.128,可以ping通。 转载不是错: Ubuntu命令行修改网络配置方法 /etc/network/interfaces打开后里面可设置DHCP或手动设置静态ip。前面auto eth0,让网卡开机自动挂载. 1. 以D php包管理工具推荐 dcj3sjt126com PHPComposer http://www.phpcomposer.com/ Composer是 PHP 用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你安装这些依赖的库文件。 中文文档 入门指南 下载 安装包列表 Composer 中国镜像 Gson使用四(TypeAdapter) eksliang jsongsonGson自定义转换器gsonTypeAdapter 转载请出自出处:http://eksliang.iteye.com/blog/2175595 一.概述 Gson的TypeAapter可以理解成自定义序列化和返序列化 二、应用场景举例 例如我们通常去注册时(那些外国网站),会让我们输入firstName,lastName,但是转到我们都 JQM控件之Navbar和Tabs gundumw100 htmlxmlcss 在JQM中使用导航栏Navbar是简单的。 只需要将data-role="navbar"赋给div即可: <div data-role="navbar"> <ul> <li><a href="#" class="ui-btn-active&qu 利用归并排序算法对大文件进行排序 iwindyforest java归并排序大文件分治法Merge sort 归并排序算法介绍,请参照Wikipeida zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F 基本思想: 大文件分割成行数相等的两个子文件,递归(归并排序)两个子文件,直到递归到分割成的子文件低于限制行数 低于限制行数的子文件直接排序 两个排序好的子文件归并到父文件 直到最后所有排序好的父文件归并到输入 iOS UIWebView URL拦截 啸笑天 UIWebView 本文译者:candeladiao,原文:URL filtering for UIWebView on the iPhone说明:译者在做app开发时,因为页面的javascript文件比较大导致加载速度很慢,所以想把javascript文件打包在app里,当UIWebView需要加载该脚本时就从app本地读取,但UIWebView并不支持加载本地资源。最后从下文中找到了解决方法,第一次翻译,难免有 索引的碎片整理SQL语句 macroli sql SET NOCOUNT ON DECLARE @tablename VARCHAR (128) DECLARE @execstr VARCHAR (255) DECLARE @objectid INT DECLARE @indexid INT DECLARE @frag DECIMAL DECLARE @maxfrag DECIMAL --设置最大允许的碎片数量,超过则对索引进行碎片 Angularjs同步操作http请求with $promise qiaolevip 每天进步一点点学习永无止境AngularJS纵观千象 // Define a factory app.factory('profilePromise', ['$q', 'AccountService', function($q, AccountService) { var deferred = $q.defer(); AccountService.getProfile().then(function(res) { hibernate联合查询问题 sxj19881213 sqlHibernateHQL联合查询 最近在用hibernate做项目,遇到了联合查询的问题,以及联合查询中的N+1问题。 针对无外键关联的联合查询,我做了HQL和SQL的实验,希望能帮助到大家。(我使用的版本是hibernate3.3.2) 1 几个常识: (1)hql中的几种join查询,只有在外键关联、并且作了相应配置时才能使用。 (2)hql的默认查询策略,在进行联合查询时,会产 struts2.xml wuai struts <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache 按字母分类: ABCDEFGHIJKLMNOPQRSTUVWXYZ其他