25种代码坏味道总结+优化示例

前言

什么样的代码是好代码呢?好的代码应该命名规范、可读性强、扩展性强、健壮性......而不好的代码又有哪些典型特征呢?这25种代码坏味道大家要注意啦

1. Duplicated Code (重复代码)

重复代码就是不同地点,有着相同的程序结构。一般是因为需求迭代比较快,开发小伙伴担心影响已有功能,就复制粘贴造成的。重复代码很难维护的,如果你要修改其中一段的代码逻辑,就需要修改多次,很可能出现遗漏的情况。

如何优化重复代码呢?分三种情况讨论:

  1. 同一个类的两个函数含有相同的表达式

class A {public void method1() {doSomething1doSomething2doSomething3}public void method2() {doSomething1doSomething2doSomething4}
}

优化手段:可以使用Extract Method(提取公共函数) 抽出重复的代码逻辑,组成一个公用的方法。

class A {public void method1() {commonMethod();doSomething3}public void method2() {commonMethod();doSomething4}public void commonMethod(){doSomething1doSomething2}
}
  1. 两个互为兄弟的子类内含相同的表达式

class A extend C {public void method1() {doSomething1doSomething2doSomething3}
}class B extend C {public void method1() {doSomething1doSomething2doSomething4}
}

优化手段:对两个类都使用Extract Method(提取公共函数),然后把抽取出来的函数放到父类中。

class C {public void commonMethod(){doSomething1doSomething2}
}
class A extend C {public void method1() {commonMethod();doSomething3}
}class B extend C {public void method1() {commonMethod();doSomething4}
}
  1. 两个毫不相关的类出现重复代码

如果是两个毫不相关的类出现重复代码,可以使用Extract Class将重复代码提炼到一个类中。这个新类可以是一个普通类,也可以是一个工具类,看具体业务怎么划分吧。

2 .Long Method (长函数)

长函数是指一个函数方法几百行甚至上千行,可读性大大降低,不便于理解。反例如下:

public class Test {private String name;private Vector<Order> orders = new Vector<Order>();public void printOwing() {//print bannerSystem.out.println("****************");System.out.println("*****customer Owes *****");System.out.println("****************");//calculate totalAmountEnumeration env = orders.elements();double totalAmount = 0.0;while (env.hasMoreElements()) {Order order = (Order) env.nextElement();totalAmount += order.getAmout();}//print detailsSystem.out.println("name:" + name);System.out.println("amount:" + totalAmount);......}
}

可以使用Extract Method,抽取功能单一的代码段,组成命名清晰的小函数,去解决长函数问题,正例如下:

public class Test {private String name;private Vector<Order> orders = new Vector<Order>();public void printOwing() {//print bannerprintBanner();//calculate totalAmountdouble totalAmount = getTotalAmount();//print detailsprintDetail(totalAmount);}void printBanner(){System.out.println("****************");System.out.println("*****customer Owes *****");System.out.println("****************");}double getTotalAmount(){Enumeration env = orders.elements();double totalAmount = 0.0;while (env.hasMoreElements()) {Order order = (Order) env.nextElement();totalAmount += order.getAmout();}return totalAmount;}void printDetail(double totalAmount){System.out.println("name:" + name);System.out.println("amount:" + totalAmount);}}

3.  Large Class (过大的类)

一个类做太多事情,维护了太多功能,可读性变差,性能也会下降。举个例子,订单相关的功能你放到一个类A里面,商品库存相关的也放在类A里面,积分相关的还放在类A里面...反例如下:

Class A{public void printOrder(){System.out.println("订单");}public void printGoods(){System.out.println("商品");}public void printPoints(){System.out.println("积分");}
}

试想一下,乱七八糟的代码块都往一个类里面塞,还谈啥可读性。应该按单一职责,使用Extract Class把代码划分开,正例如下:

Class Order{public void printOrder(){System.out.println("订单");}
}Class Goods{public void printGoods(){System.out.println("商品");}
}Class Points{   public void printPoints(){System.out.println("积分");}}
}

4. Long Parameter List (过长参数列)

方法参数数量过多的话,可读性很差。如果有多个重载方法,参数很多的话,有时候你都不知道调哪个呢。并且,如果参数很多,做新老接口兼容处理也比较麻烦。

public void getUserInfo(String name,String age,String sex,String mobile){// do something ...
}

如何解决过长参数列问题呢?将参数封装成结构或者类,比如我们将参数封装成一个DTO类,如下:

public void getUserInfo(UserInfoParamDTO userInfoParamDTO){// do something ...
}class UserInfoParamDTO{private String name;private String age; private String sex;private String mobile;
}

5. Divergent Change (发散式变化)

对程序进行维护时, 如果添加修改组件, 要同时修改一个类中的多个方法, 那么这就是 Divergent Change。举个汽车的例子,某个汽车厂商生产三种品牌的汽车:BMW、Benz和LaoSiLaiSi,每种品牌又可以选择燃油、纯电和混合动力。反例如下

/***  公众号:捡田螺的小男孩*/
public class Car {private String name;void start(Engine engine) {if ("HybridEngine".equals(engine.getName())) {System.out.println("Start Hybrid Engine...");} else if ("GasolineEngine".equals(engine.getName())) {System.out.println("Start Gasoline Engine...");} else if ("ElectricEngine".equals(engine.getName())) {System.out.println("Start Electric Engine");}}void drive(Engine engine,Car car) {this.start(engine);System.out.println("Drive " + getBrand(car) + " car...");}String getBrand(Car car) {if ("Baoma".equals(car.getName())) {return "BMW";} else if ("BenChi".equals(car.getName())) {return "Benz";} else if ("LaoSiLaiSi".equals(car.getName())) {return "LaoSiLaiSi";}return null;}}

如果新增一种品牌新能源电车,然后它的启动引擎是核动力呢,那么就需要修改Car类的startgetBrand方法啦,这就是代码坏味道:Divergent Change (发散式变化)

如何优化呢?一句话总结:拆分类,将总是一起变化的东西放到一块

  • 运用提炼类(Extract Class) 拆分类的行为。

  • 如果不同的类有相同的行为,提炼超类(Extract Superclass) 和 提炼子类(Extract Subclass)。

正例如下:

因为Engine是独立变化的,所以提取一个Engine接口,如果新加一个启动引擎,多一个实现类即可。如下:

//IEngine
public interface IEngine {void start();
}public class HybridEngineImpl implements IEngine { @Overridepublic void start() {System.out.println("Start Hybrid Engine...");}
}

因为drive方法依赖于Car,IEngine,getBand方法;getBand方法是变化的,也跟Car是有关联的,所以可以搞个抽象Car的类,每个品牌汽车继承于它即可,如下

public abstract class AbstractCar {protected IEngine engine;public AbstractCar(IEngine engine) {this.engine = engine;}public abstract void drive();
}//奔驰汽车
public class BenzCar extends AbstractCar {public BenzCar(IEngine engine) {super(engine);}@Overridepublic void drive() {this.engine.start();System.out.println("Drive " + getBrand() + " car...");}private String getBrand() {return "Benz";}
}//宝马汽车
public class BaoMaCar extends AbstractCar {public BaoMaCar(IEngine engine) {super(engine);}@Overridepublic void drive() {this.engine.start();System.out.println("Drive " + getBrand() + " car...");}private String getBrand() {return "BMW";}
}

细心的小伙伴,可以发现不同子类BaoMaCar和BenzCar的drive方法,还是有相同代码,所以我们可以再扩展一个抽象子类,把drive方法推进去,如下:

public abstract class AbstractRefinedCar extends AbstractCar {public AbstractRefinedCar(IEngine engine) {super(engine);}@Overridepublic void drive() {this.engine.start();System.out.println("Drive " + getBrand() + " car...");}abstract String getBrand();
}//宝马
public class BaoMaRefinedCar extends AbstractRefinedCar {public BaoMaRefinedCar(IEngine engine) {super(engine);}@OverrideString getBrand() {return  "BMW";}
}

如果再添加一个新品牌,搞个子类,继承AbstractRefinedCar即可,如果新增一种启动引擎,也是搞个类实现IEngine接口即可

6. Shotgun Surgery(散弹式修改)

当你实现某个小功能时,你需要在很多不同的类做出小修改。这就是Shotgun Surgery(散弹式修改)。它跟发散式变化(Divergent Change) 的区别就是,它指的是同时对多个类进行单一的修改,发散式变化指在一个类中修改多处。反例如下

public class DbAUtils {@Value("${db.mysql.url}")private String mysqlDbUrl;...
}public class DbBUtils {@Value("${db.mysql.url}")private String mysqlDbUrl;...
}

多个类使用了db.mysql.url这个变量,如果将来需要切换mysql到别的数据库,如Oracle,那就需要修改多个类的这个变量!

如何优化呢?将各个修改点,集中到一起,抽象成一个新类。

可以使用 Move Method (搬移函数)和 Move Field (搬移字段)把所有需要修改的代码放进同一个类,如果没有合适的类,就去new一个。

正例如下:

public class DbUtils {@Value("${db.mysql.url}")private String mysqlDbUrl;...
}

7. Feature Envy (依恋情节)

某个函数为了计算某个值,从另一个对象那里调用几乎半打的取值函数。通俗点讲,就是一个函数使用了大量其他类的成员,有人称之为红杏出墙的函数。反例如下:

public class User{private Phone phone;public User(Phone phone){this.phone = phone;}public void getFullPhoneNumber(Phone phone){System.out.println("areaCode:" + phone.getAreaCode());System.out.println("prefix:" + phone.getPrefix());System.out.println("number:" + phone.getNumber());}
}

如何解决呢?在这种情况下,你可以考虑将这个方法移动到它使用的那个类中。例如,要将 getFullPhoneNumber()User 类移动到Phone类中,因为它调用了Phone类的很多方法。

8. Data Clumps(数据泥团)

数据项就像小孩子,喜欢成群结队地呆在一块。如果一些数据项总是一起出现的,并且一起出现更有意义的,就可以考虑,按数据的业务含义来封装成数据对象。反例如下:

public class User {private String firstName;private String lastName;private String province;private String city;private String area;private String street;
}

正例:

public class User {private UserName username;private Adress adress;
}class UserName{private String firstName;private String lastName;
}
class Address{private String province;private String city;private String area;private String street;
}

9. Primitive Obsession (基本类型偏执)

多数编程环境都有两种数据类型,结构类型和基本类型。这里的基本类型,如果指Java语言的话,不仅仅包括那八大基本类型哈,也包括String等。如果是经常一起出现的基本类型,可以考虑把它们封装成对象。我个人觉得它有点像Data Clumps(数据泥团) 举个反例如下:

// 订单
public class Order {private String customName;private String address;private Integer orderId;private Integer price;
}

正例:

// 订单类
public class Order {private Custom custom;private Integer orderId;private Integer price;
}
// 把custom相关字段封装起来,在Order中引用Custom对象
public class Custom {private String name;private String address;
}

当然,这里不是所有的基本类型,都建议封装成对象,有关联或者一起出现的,才这么建议哈。

10. Switch Statements (Switch 语句)

这里的Switch语句,不仅包括Switch相关的语句,也包括多层if...else的语句哈。很多时候,switch语句的问题就在于重复,如果你为它添加一个新的case语句,就必须找到所有的switch语句并且修改它们。

示例代码如下:

    String medalType = "guest";if ("guest".equals(medalType)) {System.out.println("嘉宾勋章");} else if ("vip".equals(medalType)) {System.out.println("会员勋章");} else if ("guard".equals(medalType)) {System.out.println("守护勋章");}...

这种场景可以考虑使用多态优化:

//勋章接口
public interface IMedalService {void showMedal();
}//守护勋章策略实现类
public class GuardMedalServiceImpl implements IMedalService {@Overridepublic void showMedal() {System.out.println("展示守护勋章");}
}
//嘉宾勋章策略实现类
public class GuestMedalServiceImpl implements IMedalService {@Overridepublic void showMedal() {System.out.println("嘉宾勋章");}
}//勋章服务工厂类
public class MedalServicesFactory {private static final Map<String, IMedalService> map = new HashMap<>();static {map.put("guard", new GuardMedalServiceImpl());map.put("vip", new VipMedalServiceImpl());map.put("guest", new GuestMedalServiceImpl());}public static IMedalService getMedalService(String medalType) {return map.get(medalType);}
}

当然,多态只是优化的一个方案,一个方向。如果只是单一函数有些简单选择示例,并不建议动不动就使用动态,因为显得有点杀鸡使用牛刀了。

11.Parallel Inheritance Hierarchies( 平行继承体系)

平行继承体系 其实算是Shotgun Surgery的特殊情况啦。当你为A类的一个子类Ax,也必须为另一个类B相应的增加一个子类Bx。

解决方法:遇到这种情况,就要消除两个继承体系之间的引用,有一个类是可以去掉继承关系的。

12. Lazy Class (冗赘类)

把这些不再重要的类里面的逻辑,合并到相关类,删掉旧的。一个比较常见的场景就是,假设系统已经有日期工具类DateUtils,有些小伙伴在开发中,需要用到日期转化等,不管三七二十一,又自己实现一个新的日期工具类。

13. Speculative Generality(夸夸其谈未来性)

尽量避免过度设计的代码。例如:

  • 只有一个if else,那就不需要班门弄斧使用多态;

  • 如果某个抽象类没有什么太大的作用,就运用Collapse Hierarchy(折叠继承体系)

  • 如果函数的某些参数没用上,就移除。

14. Temporary Field(令人迷惑的临时字段)

某个实例变量仅为某种特定情况而定而设,这样的代码就让人不易理解,我们称之为 Temporary Field(令人迷惑的临时字段)。反例如下:

public class PhoneAccount {private double excessMinutesCharge;private static final double RATE = 8.0;public double computeBill(int minutesUsed, int includedMinutes) {excessMinutesCharge = 0.0;int excessMinutes = minutesUsed - includedMinutes;if (excessMinutes >= 1) {excessMinutesCharge = excessMinutes * RATE;}return excessMinutesCharge;}public double chargeForExcessMinutes(int minutesUsed, int includedMinutes) {computeBill(minutesUsed, includedMinutes);return excessMinutesCharge;}
}

思考一下,临时字段excessMinutesCharge是否多余呢?

15. Message Chains (过度耦合的消息链)

当你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象...这就是消息链。实际代码中,你看到的可能是一长串getThis()或一长串临时变量。反例如下:

A.getB().getC().getD().getTianLuoBoy().getData();

A想要获取需要的数据时,必须要知道B,又必须知道C,又必须知道D...其实A需要知道得太多啦,回头想下封装性,嘻嘻。其实可以通过拆函数或者移动函数解决,比如由B作为代理,搞个函数直接返回A需要数据。

16. Middle Man (中间人)

对象的基本特征之一就是封装,即对外部世界隐藏其内部细节。封装往往伴随委托,过度运用委托就不好:某个类接口有一半的函数都委托给其他类。可以使用Remove Middle Man优化。反例如下:

A.B.getC(){return C.getC();
}

其实,A可以直接通过C去获取C,而不需要通过B去获取。

17. Inappropriate Intimacy(狎昵关系)

如果两个类过于亲密,过分狎昵,你中有我,我中有你,两个类彼此使用对方的私有的东西,就是一种坏代码味道。我们称之为Inappropriate Intimacy(狎昵关系)

建议尽量把有关联的方法或属性抽离出来,放到公共类,以减少关联。

18. Alternative Classes with Different Interfaces (异曲同工的类)

A类的接口a,和B类的接口b,做的的是相同一件事,或者类似的事情。我们就把A和B叫做异曲同工的类。

可以通过重命名,移动函数,或抽象子类等方式优化

19. Incomplete Library Class (不完美的类库)

大多数对象只要够用就好,如果类库构造得不够好,我们不可能修改其中的类使它完成我们希望完成的工作。可以酱紫:包一层函数或包成新的类

20. Data Class (纯数据类)

什么是Data Class? 它们拥有一些字段,以及用于访问(读写)这些字段的函数。这些类很简单,仅有公共成员变量,或简单操作的函数。

如何优化呢?将相关操作封装进去,减少public成员变量。比如:

  • 如果拥有public字段-> Encapsulate Field

  • 如果这些类内含容器类的字段,应该检查它们是不是得到了恰当地封装-> Encapsulate Collection封装起来

  • 对于不该被其他类修改的字段-> Remove Setting Method->找出取值/设置函数被其他类运用的地点-> Move Method 把这些调用行为搬移到Data Class来。如果无法搬移整个函数,就运用Extract Method产生一个可被搬移的函数->Hide Method把这些取值/设置函数隐藏起来。

21. Refused Bequest (被拒绝的馈赠)

子类应该继承父类的数据和函数。子类继承得到所有函数和数据,却只使用了几个,那就是继承体系设计错误,需要优化。

  • 需要为这个子类新建一个兄弟类->Push Down MethodPush Down Field把所有用不到的函数下推给兄弟类,这样一来,超类就只持有所有子类共享的东西。所有超类都应该是抽象的。

  • 如果子类复用了超类的实现,又不愿意支持超类的接口,可以不以为然。但是不能胡乱修改继承体系->Replace Inheritance with Delegation(用委派替换继承).

22. Comments (过多的注释)

这个点不是说代码不建议写注释哦,而是,建议大家避免用注释解释代码,避免过多的注释。这些都是常见注释的坏味道:

  • 多余的解释

  • 日志式注释

  • 用注释解释变量等

  • ...

如何优化呢?

  • 方法函数、变量的命名要规范、浅显易懂、避免用注释解释代码。

  • 关键、复杂的业务,使用清晰、简明的注释

23. 神奇命名

方法函数、变量、类名、模块等,都需要简单明了,浅显易懂。避免靠自己主观意识瞎起名字。

反例:

boolean test = chenkParamResult(req);

正例:

boolean isParamPass = chenkParamResult(req);

24. 神奇魔法数

日常开发中,经常会遇到这种代码:

if(userType==1){//doSth1
}else If( userType ==2){//doSth2
}
...

代码中的这个1和2都表示什么意思呢?再比如setStatus(1)中的1又表示什么意思呢?看到类似坏代码,可以这两种方式优化:

  • 新建个常量类,把一些常量放进去,统一管理,并且写好注释;

  • 建一个枚举类,把相关的魔法数字放到一起管理。

25. 混乱的代码层次调用

我们代码一般会分dao层service层controller层

  • dao层主要做数据持久层的工作,与数据库打交道。

  • service层主要负责业务逻辑处理。

  • controller层负责具体的业务模块流程的控制。

所以一般就是controller调用serviceservicedao。如果你在代码看到controller直接调用dao,那可以考虑是否优化啦。反例如下

@RestController("user")
public class UserController {Autowiredprivate UserDao userDao;@RequestMapping("/queryUserInfo")public String queryUserInfo(String userName) {return userDao.selectByUserName(userName);}
}

参考与感谢

  • 软工实验:常见的代码坏味道以及重构举例[2]

  • 22种代码的坏味道,一句话概括[3]

  • 【重构】 代码的坏味道总结 Bad Smell[4]

  • Code Smell[5]

  • 《重构改善既有代码的设计》


往期推荐

ThreadLocal内存溢出代码演示和原因分析!


SimpleDateFormat线程不安全的5种解决方案!


2万字!66道并发面试题及答案



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

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

相关文章

滚动照片抽奖软件

CODE GitHub 源码 1、女友说很丑的一个软件 说个最近的事情&#xff0c;女友公司过年了要搞活动&#xff0c;需要个抽奖的环节&#xff0c;当时就问我能不能给做一个&#xff0c;正好我也没啥事儿&#xff0c;就在周末的时候用C#做了一个&#xff0c;虽然派上用场了&#xf…

11个小技巧,玩转Spring!

前言最近有些读者私信我说希望后面多分享spring方面的文章&#xff0c;这样能够在实际工作中派上用场。正好我对spring源码有过一定的研究&#xff0c;并结合我这几年实际的工作经验&#xff0c;把spring中我认为不错的知识点总结一下&#xff0c;希望对您有所帮助。一 如何获取…

synchronized 的超多干货!

synchronized 这个关键字的重要性不言而喻&#xff0c;几乎可以说是并发、多线程必须会问到的关键字了。synchronized 会涉及到锁、升级降级操作、锁的撤销、对象头等。所以理解 synchronized 非常重要&#xff0c;本篇文章就带你从 synchronized 的基本用法、再到 synchronize…

团队项目—第二阶段第三天

昨天&#xff1a;快捷键的设置已经实现了 今天&#xff1a;协助成员实现特色功能之一 问题&#xff1a;技术上遇到了困难&#xff0c;特色功能一直没太大的进展。网上相关资料不是那么多&#xff0c;我们无从下手。 有图有真相&#xff1a; 转载于:https://www.cnblogs.com/JJJ…

不重启JVM,替换掉已经加载的类,偷天换日?

来源 | 美团技术博客在遥远的希艾斯星球爪哇国塞沃城中&#xff0c;两名年轻的程序员正在为一件事情苦恼&#xff0c;程序出问题了&#xff0c;一时看不出问题出在哪里&#xff0c;于是有了以下对话&#xff1a;“Debug一下吧。”“线上机器&#xff0c;没开Debug端口。”“看日…

[nodejs] 利用openshift 撰寫應用喔

2019独角兽企业重金招聘Python工程师标准>>> 朋友某一天告訴我,可以利用openshift來架站,因為他架了幾個nodejs應用放在上面,我也來利用這個平台架看看,似乎因為英文不太行,搞很久啊!! 先來架一個看看,不過架好之後,可以有三個應用,每個應用有1G的空間,用完就沒啦~~…

详解4种经典的限流算法

最近&#xff0c;我们的业务系统引入了Guava的RateLimiter限流组件&#xff0c;它是基于令牌桶算法实现的,而令牌桶是非常经典的限流算法。本文将跟大家一起学习几种经典的限流算法。限流是什么?维基百科的概念如下&#xff1a;In computer networks, rate limiting is used t…

css clearfix_如何使用CSS清除浮点数(clearfix)?

css clearfixIntroduction: 介绍&#xff1a; Dealing with various elements on a website or web page can sometimes prove to create many problems hence one should be aware of many properties, tricks or ways to cope with those problems. We do not want our webs…

将你的Windows,快速打造成Docker工作站!

手里的macbook因为键盘问题返厂维修了&#xff0c;只好抱起了久违的Windows。首先面临的&#xff0c;就是Docker问题。docker好用&#xff0c;但安装麻烦&#xff0c;用起来也命令繁多。一个小白&#xff0c;如何打造舒适的docker环境&#xff0c;是一个非常有挑战的问题。本文…

漫画:什么是JVM的垃圾回收?

————— 第二天 —————————————————下面我们一起来研究这三个问题。问题1&#xff1a;哪些是需要回收的&#xff1f;首先我们需要知道如何哪些垃圾需要回收&#xff1f;判断对象是否需要回收有两种算法。一种是引用计数算法、一种是可达性分析算法。引用计…

48张图|手摸手教你性能监控、压测和调优

本文主要内容一、何为压力测试1.1、 大白话解释性能压测是什么&#xff1a;就是考察当前软件和硬件环境下&#xff0c;系统所能承受的最大负荷&#xff0c;并帮助找出系统的瓶颈所在。性能压测的目的&#xff1a;为了系统在线上的处理能力和稳定性维持在一个标准范围内&#xf…

Java生成随机数的4种方式,以后就用它了!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在 Java 中&#xff0c;生成随机数的场景有很多&#xff0c;所以本文我们就来盘点一下 4 种生成随机数的方式&#xff0c;以…

Everything是如何搜索的

写在前面 使用了Everything之后&#xff0c;一直对他的搜索速度感兴趣&#xff0c;在网上也看了很多对其原理的揭秘&#xff0c;终于有空找了个源码研究了一下&#xff0c;原理就是对NTFS的USN特性进行使用。 原理 详细解释我参照别人家的博客来一段&#xff1a; 当扇区的文…

漫话:如何给女朋友解释String对象是不可变的?

String的不变性String在Java中特别常用&#xff0c;相信很多人都看过他的源码&#xff0c;在JDK中&#xff0c;关于String的类声明是这样的&#xff1a;public final class String implements java.io.Serializable, Comparable<String>, CharSequence { }可以看到&#…

XenServer 6.5实战系列之十一:Install Update For XenServer 6.5

为了保证XenServer主机的安全及功能的更新&#xff0c;在企业环境中我们需要定期的到Citrix官网或通过XenCenter进行下载和更新。今天我们会从在线和离线两种不同的方法进行Update的安装。更新补丁之前请务必阅读对应Update的相关资料、注意事项和做好备份。1. 离线安装更新在…

机器学习 属性_属性关系文件格式| 机器学习

机器学习 属性Today, we will be looking at the use of attribute relation file format for machine learning in java and we would be writing a small java code to convert the popularly used .csv file format into the arff (Attribute relation file format). This f…

C#标记废弃方法

一、普通用法 在C#中&#xff0c;如果一个方法我们不再使用&#xff0c;我们可以将其标记为“废弃”的方法&#xff0c;只需要在方法前&#xff0c;加一个[Obsolete]即可&#xff1b; [Obsolete] public void BiuBiuBiu(){// 嘿嘿嘿 }废弃方法并非不能使用&#xff0c;而是在…

阿里二面一问MySQL就开始野了,抓着底层原理不撒手啊!

最近项目增加&#xff0c;缺人手&#xff0c;面试不少&#xff0c;但匹配的人少的可怜。跟其他组的面试官聊&#xff0c;他也抱怨了一番&#xff0c;说候选人有点儿花拳绣腿&#xff0c;回答问题不落地&#xff0c;拿面试最常问的MySQL来说&#xff0c;并不只是懂“增删改查”、…

[转]“Ceph浅析”系列之(—)—Ceph概况

转载自&#xff1a;http://yizhaolingyan.net/?p11本文将对Ceph的基本情况进行概要介绍&#xff0c;以期读者能够在不涉及技术细节的情况下对Ceph建立一个初步印象。2.1 什么是Ceph&#xff1f;Ceph的官方网站Ceph.com上用如下这句话简明扼要地定义了Ceph&#xff1a;“Ceph…

关于C#监视剪贴板信息

##1、常规方法 在C#中&#xff0c;有一个常规检测剪贴板的方法&#xff0c;用的是 System.Windows.Forms.Clipboard&#xff1b; 使用起来很简单&#xff0c;代码如下&#xff1a; /// <summary> /// 设置剪贴板的文本内容 /// </summary> /// <param name&qu…