《重构-改善既有代码的设计》-第1例:租赁影片(1)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

买了《重构 - 改善既有代码的设计 》一书,一直没有好好看,大致过了下也觉得只是有点点印象而已,最后还是决定把代码敲一次,记录一下这些学习过程。

 

第一例:租赁影片

程序说明:顾客租了哪些影片,租期多长,根据租赁时间和影片类型算出费用和积分。

1. 分解并重组statement() 

原代码如下有3个类。 

 

package bean;
/*** 租赁订单* @author Administrator*/
public class Rental {private Movie _movie ; // 影片private int _daysRented; // 租赁天数public Rental(Movie _movie, int _daysRented) {this._movie = _movie;this._daysRented = _daysRented;}public Movie getMovie() {return _movie;}public int getDaysRented() {return _daysRented;}}

 

package bean;/*** 影片* @author Administrator*/
public class Movie {public static final int CHILDRENS = 2;  // 儿童片public static final int REGULAR = 0; // 普通片public static final int NEW_RELEASE = 1; // 新片private String _title;private int _priceCode;public Movie(String _title, int _priceCode) {this._title = _title;this._priceCode = _priceCode;}public int getPriceCode() {return _priceCode;}public void setPriceCode(int _priceCode) {this._priceCode = _priceCode;}public String getTitle() {return _title;}}

 

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){double thisAmount = 0; // 租金Rental each = (Rental)rentals.nextElement();// 确定每种片子的租金switch(each.getMovie().getPriceCode()){case Movie.REGULAR:thisAmount += 2;if(each.getDaysRented() > 2 ){thisAmount += (each.getDaysRented() - 2) * 1.5;}break;case Movie.NEW_RELEASE:thisAmount += each.getDaysRented()*3;break;case Movie.CHILDRENS:thisAmount += 1.5;if(each.getDaysRented() > 3 ){thisAmount += (each.getDaysRented() - 3) * 1.5;}break;}// 增加积分frequentRenterPoints ++;// 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(thisAmount)+"\n";totalAmount += thislAmount;}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}}


1.1 抽离switch 语句到独立方法

1.1.1 Customer类改为:

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){double thisAmount = 0; // 租金Rental each = (Rental)rentals.nextElement();thisAmount = amountFor(each); // 计算租金// 增加积分frequentRenterPoints ++; // 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(thisAmount)+"\n";totalAmount += thisAmount;}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}// 计算租金private int amountFor(Rental each){int thisAmount = 0; // 租金// 确定每种片子的租金switch(each.getMovie().getPriceCode()){case Movie.REGULAR:thisAmount += 2;if(each.getDaysRented() > 2 ){thisAmount += (each.getDaysRented() - 2) * 1.5;}break;case Movie.NEW_RELEASE:thisAmount += each.getDaysRented()*3;break;case Movie.CHILDRENS:thisAmount += 1.5;if(each.getDaysRented() > 3 ){thisAmount += (each.getDaysRented() - 3) * 1.5;}break;}return thisAmount;}}

 

 

1.1.2 注意 amountFor 方法的返回类型应该是double类型:

 Customer类改为:

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){double thisAmount = 0; // 租金Rental each = (Rental)rentals.nextElement();thisAmount = amountFor(each); // 计算租金// 增加积分frequentRenterPoints ++; // 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(thisAmount)+"\n";totalAmount += thisAmount;}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}// 计算租金private double amountFor(Rental each){double thisAmount = 0; // 租金// 确定每种片子的租金switch(each.getMovie().getPriceCode()){case Movie.REGULAR:thisAmount += 2;if(each.getDaysRented() > 2 ){thisAmount += (each.getDaysRented() - 2) * 1.5;}break;case Movie.NEW_RELEASE:thisAmount += each.getDaysRented()*3;break;case Movie.CHILDRENS:thisAmount += 1.5;if(each.getDaysRented() > 3 ){thisAmount += (each.getDaysRented() - 3) * 1.5;}break;}return thisAmount;}}


1.3  变量名称应该见名知意:好的代码应该清楚的表达出自己的功能,变量名称是代码清晰的一个关键。

 

amountFor方法中局部变量 thisAmount , 参数each 要改名。

改变量名 , Customer类改为:

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){double thisAmount = 0; // 租金Rental each = (Rental)rentals.nextElement();thisAmount = amountFor(each); // 计算租金// 增加积分frequentRenterPoints ++; // 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(thisAmount)+"\n";totalAmount += thisAmount;}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}// 计算租金private double amountFor(Rental aRental){double result = 0; // 租金// 确定每种片子的租金switch(aRental.getMovie().getPriceCode()){case Movie.REGULAR:result += 2;if(aRental.getDaysRented() > 2 ){result += (aRental.getDaysRented() - 2) * 1.5;}break;case Movie.NEW_RELEASE:result += aRental.getDaysRented()*3;break;case Movie.CHILDRENS:result += 1.5;if(aRental.getDaysRented() > 3 ){result += (aRental.getDaysRented() - 3) * 1.5;}break;}return result;}}

 

 

1.4 函数应该放在它所使用的数据所属的对象中, 顾客租金的计算应该移动到Rental类中去。

 

 

 

Rental 类改为 :  (计算租金方法去掉参数并改名 )

 

package bean;
/*** 租赁订单* @author Administrator*/
public class Rental {private Movie _movie ; // 影片private int _daysRented; // 租赁天数public Rental(Movie _movie, int _daysRented) {this._movie = _movie;this._daysRented = _daysRented;}public Movie getMovie() {return _movie;}public int getDaysRented() {return _daysRented;}// 计算租金double getCharge(){double result = 0; // 租金// 确定每种片子的租金switch(getMovie().getPriceCode()){case Movie.REGULAR:result += 2;if(getDaysRented() > 2 ){result += (getDaysRented() - 2) * 1.5;}break;case Movie.NEW_RELEASE:result += getDaysRented()*3;break;case Movie.CHILDRENS:result += 1.5;if(getDaysRented() > 3 ){result += (getDaysRented() - 3) * 1.5;}break;}return result;}}


原顾客类中amountFor方法直接调用计算租金方法即可,Customer 类改为:

 

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){double thisAmount = 0; // 租金Rental each = (Rental)rentals.nextElement();thisAmount = amountFor(each); // 计算租金// 增加积分frequentRenterPoints ++; // 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(thisAmount)+"\n";totalAmount += thisAmount;}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}// 计算租金private double amountFor(Rental aRental){return aRental.getCharge();}}


1.5  去掉旧函数amountFor,直接调用新函数getCharge。Customer类改为 : 

 

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){double thisAmount = 0; // 租金Rental each = (Rental)rentals.nextElement();thisAmount = each.getCharge(); // 计算租金// 增加积分frequentRenterPoints ++; // 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(thisAmount)+"\n";totalAmount += thisAmount;}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}}


1.6  尽量去掉临时变量,临时变量会导致大量参数的传递,没有必要。 thisAmount 是个多余的临时变量,直接去掉。

 

Customer 改为:

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){Rental each = (Rental)rentals.nextElement();// 增加积分frequentRenterPoints ++; // 新片+租赁时间达2天  积分+1 if(each.getMovie().getPriceCode() == Movie.NEW_RELEASE && each.getDaysRented() > 1){frequentRenterPoints ++;}// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(each.getCharge())+"\n";totalAmount += each.getCharge();}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}}

 

1.7 把积分计算方法放到Rental类中,写为常客积分计算方法(getFrequentRenterPoints),并改变Customer类中积分计算代码 。

 

Rental类改为:

 

package bean;
/*** 租赁订单* @author Administrator*/
public class Rental {private Movie _movie ; // 影片private int _daysRented; // 租赁天数public Rental(Movie _movie, int _daysRented) {this._movie = _movie;this._daysRented = _daysRented;}public Movie getMovie() {return _movie;}public int getDaysRented() {return _daysRented;}// 计算租金double getCharge(){double result = 0; // 租金// 确定每种片子的租金switch(getMovie().getPriceCode()){case Movie.REGULAR:result += 2;if(getDaysRented() > 2 ){result += (getDaysRented() - 2) * 1.5;}break;case Movie.NEW_RELEASE:result += getDaysRented()*3;break;case Movie.CHILDRENS:result += 1.5;if(getDaysRented() > 3 ){result += (getDaysRented() - 3) * 1.5;}break;}return result;}// 常客积分计算int getFrequentRenterPoints(){// 增加积分int frequentRenterPoints =0;frequentRenterPoints++; // (新片+租赁时间达2天  积分+1 )if(getMovie().getPriceCode() == Movie.NEW_RELEASE && getDaysRented() > 1){frequentRenterPoints ++;}return frequentRenterPoints;}}


Customer类中statement方法改为:

 

 

/*** 生成订单* @return*/public String statement(){double totalAmount = 0; // 总租金 int frequentRenterPoints = 0; // 积分Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){Rental each = (Rental)rentals.nextElement();// 积分frequentRenterPoints += each.getFrequentRenterPoints();// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(each.getCharge())+"\n";totalAmount += each.getCharge();}// 页脚result +="Amount owed is "+ String.valueOf(totalAmount)+"\n";result +="You eared "+String.valueOf(frequentRenterPoints)+"frequent renter points";return result;}

 

1.8 去掉statement方法中的2个临时变量:totalAmount 和 frequentRenterPoints 。抽离出对应计算方法,并调用。

 

Customer 类改为:

 

package bean;import java.util.Enumeration;
import java.util.Vector;/*** 顾客* @author Administrator*/
public class Customer {private String _name; // 顾客名字private Vector _rentals = new Vector();  // 租赁订单数组public Customer(String name) {super();this._name = name;}public void addRental(Rental arg){_rentals.addElement(arg);}public String getName() {return _name;}/*** 生成订单* @return*/public String statement(){Enumeration rentals = _rentals.elements();String result = "Rental Record for "+ getName() + "\n";while( rentals.hasMoreElements()){Rental each = (Rental)rentals.nextElement();// 本次租赁记录说明result += "\t"+each.getMovie().getTitle()+"\t"+ String.valueOf(each.getCharge())+"\n";}// 页脚result +="Amount owed is "+ String.valueOf(getTotalCharge())+"\n";result +="You eared "+String.valueOf(getTotalFrequentRenterPoints())+"frequent renter points";return result;}// 计算总积分private int getTotalFrequentRenterPoints(){int result = 0;Enumeration rentals = _rentals.elements();while(rentals.hasMoreElements()){Rental each = (Rental)rentals.nextElement();result += each.getFrequentRenterPoints();}return result;}// 计算总租金private double getTotalCharge(){double result = 0;Enumeration rentals = _rentals.elements();while(rentals.hasMoreElements()){Rental each = (Rental)rentals.nextElement();result += each.getCharge();}return result;}}

 

本步改写作用说明:

 

 这里虽然从1个循环变为3个,但是多了2个查询函数。

1)  使得Customer 类中的任何代码都可以调用这些查询函数。

2)  若系统其它部分需要这些信息,也可以轻松地将查询函数加入 Customer 类接口。而若没有这些查询波函数,其它函数就必须了解  Rental 类,并自行建立循环。

 

 

1.9 加功能:打印凭条。

statement 方法改为 htmlStatement :

 

 

/*** 生成订单(打印凭条)* @return*/public String htmlStatement(){Enumeration rentals = _rentals.elements();String result = "<P><H1>Rentals for <EM> "+ getName() + "</EM></H1></P>\n";while( rentals.hasMoreElements()){Rental each = (Rental)rentals.nextElement();// 本次租赁记录说明result += each.getMovie().getTitle()+":"+ String.valueOf(each.getCharge())+"<BR>\n";}// 页脚result +="<P>You owe <EM>"+ String.valueOf(getTotalCharge())+"</EM></P>\n";result +="<P> on this rental you earned <EM> "+String.valueOf(getTotalFrequentRenterPoints())+"</EM> frequent renter points </P>";return result;}

 

 

 

 

 

未完,见  : 重构-改善既有代码的设计-第1例:租赁影片(2)

 

 

 

 

 

 

 

 

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

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

相关文章

java类加public和不加public

加public表示全局类&#xff0c;该类可以import到任何类内。不加public默认为保留类&#xff0c;只能被同一个包内的其他类引用。

STL数据结构

STL数据结构 1.priority_queue #include<queue> pritority<int>q;(大根堆) priority_queue<int,vector<int>,greater<int> >q;(小根堆) struct no{ int x,v; bool operator <(const no &T)const{return v>T.v;} // v值xiao的优先 }; q…

《netty实战》阅读笔记(2)——Netty 的数据容器ByteBuf

ByteBuffer 当我们进行数据传输的时候&#xff0c;往往需要使用到缓冲区&#xff0c;常用的缓冲区就是JDK NIO类库提供的java.nio.Buffer。 实际上&#xff0c;7种基础类型&#xff08;Boolean除外&#xff09;都有自己的缓冲区实现&#xff0c;对于NIO编程而言&#xff0c;我们…

JAVA HASHMAP 用法

import java.util.HashMap;public class Student { String name; String sex; public Student(String n,String s) { namen; sexs; } public String toString(){ return ("姓名:"name"\n""性别:"sex"\n…

有了二叉查找树、平衡树为啥还需要红黑树?

参考文章&#xff1a; 有了二叉查找树、平衡树为啥还需要红黑树&#xff1f; 漫画AVL树 谢谢作者分享&#xff01;

32位Windows7上8G内存使用感受+xp 32位下使用8G内存

我推荐做开发的朋友:赶快加入8G的行列吧....呵呵..超爽...速度超快...基本没有等待的概念...深有体会... 为什么要使用8G内存&#xff1f;在国内外各大论坛上&#xff0c;这都是一个有争议的问题。问题的反方论据非常充分&#xff1a; 除了少数专业领域&#xff0c;大多数应用程…

《重构-改善既有代码的设计》-第1例:租赁影片(2)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 上接 重构-改善既有代码的设计-第1例&#xff1a;租赁影片&#xff08;1&#xff09; 2 运用多态取代与价格相关的条件逻辑 2.1 最好不…

elasticsearch 的查询 /_nodes/stats 各字段意思

/_nodes/stats 字段意思 “” 1 { 2 "_nodes": {3 "total": 1,4 "successful": 1,5 "failed": 06 },7 "cluster_name": "ELKTEST",8 "nodes": {9 "lnlHC8yERCKXCuAc…

看完Java的动态代理技术——Pythoner笑了

Java的动态代理常用来包装原始方法调用&#xff0c;用于增强或改写现有方法的逻辑&#xff0c;它在Java技术领域被广为使用&#xff0c;在阿里的Sofa RPC框架序列化中你能看到它的身影&#xff0c;Hibernate的实体类功能增强也是以动态代理的方式解决的&#xff0c;还有Spring吹…

shell实现从1加到100

#!/bin/bash # test"while do done"PATH/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATHsum0 for i in $(seq 1 100); do let sumi done echo "The sum is > $sum "

面试常考的数据结构Java实现

1、线性表 2、线性链表 3、栈 4、队列 5、串 6、数组 7、广义表 8、树和二叉树 二叉树&#xff1a;每个结点至多只有两棵子树&#xff08;即二叉树中不存在度大于2的结点&#xff09;&#xff0c;并且&#xff0c;二叉树的子树有左右之分&#xff0c;其次序不能任意颠倒。 二叉…

Java5线程并发库之LOCK(锁)CONDITION(条件)实现线程同步通信

为什么80%的码农都做不了架构师&#xff1f;>>> Lock&#xff08;锁&#xff09;&Condition&#xff08;条件&#xff09;实现线程同步通信 接下来介绍&#xff0c;java5线程并发库里面的锁。跟锁有关的类和接口主要是位于java.util.concurrent.locks包。 Lock…

互联网,可预见的未来

我记忆中的1998年代&#xff0c;PC迅猛发展&#xff0c;CPU速度逐年翻番&#xff0c;持续了7年&#xff0c;但下一个7年到现在&#xff0c;基本上没有太大提升&#xff1b;显示器从14英寸CRT发展到2005的21英寸LED&#xff0c;后来也没有继续进化。为什么&#xff1f;当人对计算…

什么时候用GET?什么时候用POST?

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、 GET和POST两种方法都是将数据送到服务器&#xff0c;但你该用哪一种呢&#xff1f; HTTP标准包含这两种方法是为了达到不同的目的…

逻辑运算符与逻辑表达式

1 #include <stdio.h>2 3 int main()4 {5 int a0;int b0;6 if(a&&b)//a&&ba的逻辑值为0&#xff0c;则执行else7 {8 printf("a&&b is true\n");9 } 10 else 11 { 12 printf("a&&…

linux/shell相关知识点

阿里Linux Shell脚本面试25个经典问答 Linux运维工程师12道面试题整理 感谢作者分享&#xff01;

20180601]函数与标量子查询2.txt

[20180601]函数与标量子查询2.txt --//昨天看http://www.cnblogs.com/kerrycode/p/9099507.html链接,里面提到: 通俗来将&#xff0c;当使用标量子查询的时候&#xff0c;ORACLE会将子查询结果缓存在哈希表中&#xff0c; 如果后续的记录出现同样的值&#xff0c;优化器通过缓存…

ODP 使用 ArrayBind 时可能会遇到的巨坑 'System.IConvertible' 的解决方法

Unable to cast object of type System.Nullable1[System.Int16][] to type System.IConvertible 一段代码99%不会出错&#xff0c;0.1%会报上边的错&#xff0c;debug费了老鼻子时间&#xff0c;发现此坑很深。异常是 cmd.ExecuteNonQuery() 抛的&#xff0c;实际是 para.Valu…

eclipse快速定位到错误处

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程 以前都是按着滚动条往下拉&#xff0c;找到错误的地方&#xff0c;有时比较多的时候就很麻烦。 其实eclipse是可以直接快速定位的&#x…

C语言中的“”和“”

先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如: int i 1; i i << 2; //把i里的值左移2位 也就是说,1的2进制是000...0001(这里1前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成 000...0100,也就是10进制的4,所以…