Java编程基础一

①加减乘除英语:add、subtract、multiply、divide。

②使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

是引用不能变,而不是引用的对象不能变。

当final修饰的变量是一个数值或字符串时,引用的变量值不能变。如:

final int a=10;

a=12;

则编译出错。

final String a="123";

a="456";

则编译出错。

当final修饰的变量指向某个对象的地址时,变量中对象的地址不能变,而对象的内容可以变。如:

final  List  a=new ArrayList<Integer>();

a=new ArrayList();//出错,因为a指向对象的地址,而这个地址变化了。

a.add(11);//不出错。

final StringBuffer a=new StringBuffer("immutable");

a=new StringBuffer("");//出错

a.append(" broken!");//不出错

③int是基本类型(原始类型),Integer是包装类型(封装类型)。

④多态:如

public List a=new ArrayList<T>();

接口(List接口)的引用变量(a)指向实现类(ArrayList类)的对象(new ArrayList<T>();)

a指向子类或者实现类,即a存放的是子类或者实现类的地址。另外有一个空间存放子类或者实现类的内容。

ArrayList类实现了List接口。List是接口,ArrayList类实现了该接口。

父类或者接口的引用变量,指向了子类或者具体实现类的实例对象。

⑤抽象类和接口的联系与区别。

抽象类:含有abstract修饰符的类,即为抽象类。抽象类(abstract类)不能被创建为实例对象,只能通过被子孙类继承,达到其                  功 能。

                含有抽象方法的类必定要是抽象类,必须用修饰符abstract修饰。但是抽象类,即用abstract修饰的类,里面可以含有非                  抽象方法,即不用abstract修饰的方法,即含有方法实现体的方法。即{........}。抽象方法指:有返回值,函数名,函数参                    数,但没有{}和{}里面的内容的方法。如:public abstract  int  add(int x,int y);没有{..........}。

                按理说,子孙类,需要实现抽象父类中的抽象方法。但子孙类,也可以不完全都实现抽象父类中的抽象方法。这个时候                  子孙类,必须也是抽象类,即必须也用abstract修饰符修饰。

                不能存在抽象构造方法,因为构造方法不能子孙类继承,而抽象方法需要子孙类继承。因此互相矛盾,构造方法不能被                  继承,抽象方法需要被继承,两者互相违背。因此不能存在抽象构造方法。

               不能存在抽象静态方法,从两方面看:第一,抽象方法一定是在抽象类中,有抽象方法,这个类一定是抽象类,然而抽                 象类是不能被实例化成对象的。因此,不能被分配内存。而静态(static)方法,是在类实例化成对象之前就已经分配好                 内存的,这样矛盾就出现了,抽象方法不能被分配内存,静态方法在类实例化之前就分配好了内存,一个不能被分配内                 存,一个早早就分配好了内存,互相违背,所以不能存在抽象静态方法。第二,静态方法一般是在类实例成对象之前就                已经执行的方法,静态方法肯定是要有实现体的,即{................},而抽象方法没有实现体,即{........},如果存在抽象静态                方法,此方法没有方法体,在类实例化成对象前执行,而又没有任何内容可执行,没有方法体,这样就没有意义了。

              也不能有private abstract 方法,因为private是不能被子孙类继承的。

              按理说friendly abstract方法也不行。friendly(默认类型即普通方法什么都不写时)也不能被子孙类继承。但在eclipse下                  不报错。

接口:可以说是抽象类的一种特例。接口中所有的方法必须都是抽象的。在接口中,如果没有指明,接口中的方法默认是public                abstract类型,接口中的成员变量默认是public final static类型。

抽象类和接口在语法上的区别:

抽象类可以有构造方法,而接口中不能有构造方法。
抽象类中可以有普通成员变量,而接口中不能有普通成员变量。

抽象类中可以有非抽象的方法及普通方法,而接口中必须都是抽象方法,接口中不能包含普通方法。

抽象类中的抽象方法的访问类型可以是:public,protected和默认类型(friendly,即在类中方法前面什么都不写时), 按理说friendly abstract方法也不行。friendly(默认类型即普通方法什么都不写时)也不能被子孙类继承。但在eclipse下不报错。但在接口中的抽象方法的访问类型只能是public,而且默认的就是public abstract类型。即接口中方法前面访问类型都不写时,其实就是默认类型,public abstract。

抽象类中可以包含静态方法,注意:不是抽象静态方法,上面已经说明,抽象静态方法不存在。静态方法是要有方法实现体的。因为静态方法必须有方法实现体,所以接口中不能包含静态方法,因为接口中必须都是抽象方法。接口中的方法都没有方法实现体。

抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任 意,但接口中定义的变量只能是 public static final 类型,并且默认即为 public static final 类 型。

一个类可以实现多个接口,但只能继承一个抽象类。

抽象类和接口在应用上的区别:

抽象类主要实现代码的重复利用。而接口主要在项目架构上,实现模块之间的通信。

抽象类:举个例子之前,需要了解的知识:

final修饰类,类不可被继承。final修饰方法,方法不可重写,但可以重载,而且这个方法虽然被私有化(private)了,但是可以被继承,不是真正的private,真正的private不能被子孙类继承。final修饰属性,属性不能被覆盖。

Servlet是接口,HttpServlet是实现了接口Servlet的抽象类。

HttpServletRequest与HttpServletResponse都是接口。

以下是利用抽象类代码重复利用的例子:

public  abstract class BaseServlet extends HttpServlet {

            public  final  void  service (HttpServletRequest      request ,HttpServletResponse    response)

                                                                                              throws  IOException,ServletException{

                               记录访问日志

                               进行权限判断

                                if(具有权限){

                                                try{

                                                                   doService(request,response);

                                                 }catch(Exception  e){

                                                             记录异常信息

                                                         }

                                 }

            }

          protected   abstract     void    doService(HttpServletRequest    request,HttpServletResponse  response) 

                                                                                                                            throws  IOException  ,ServletException;

        //protected 同类,子孙类,同包可以用,而其他包不能用。abstract方法,没有方法体{......},直接分号。

}

public  class  MyServlet1  extends    BaseServlet {

                  protected   void   doService(HttpServletRequest   request ,HttpServletResponse   response)

                                                                           throws    IOException ,ServletException {

                                          继承了抽象类BaseServlet,必须实现其中的抽象方法,否则,有抽象方法没有实现,则需要将此类也变                                             成抽象方法。BaseServlet只有一个抽象方法,实现了这个抽象方法doService,就不用在子类                                                              MyServlet1 增加修饰符abstract。里面写本Servlet中需要处理的具体业务逻辑代码。

                          }

}

⑥什么是匿名类。

匿名类,就是没有名称的类。匿名类就是利用父类的构造函数和自身类体构造成一个类。

格式:new 父类(){子类内容};

上面格式中的“父类”是子类需要继承或者实现外部的类或者接口

⑦子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,  接着再回到主线程又循环100,如此循环50次,请写出程序。  
  

public class ThreadTest{  
  
  
    public static void main(String[] args) {  
  
        final MyThread threads=new MyThread();  
        new Thread(  
                new Runnable(){  
                    public void run(){  
                        for(int i=1;i<=50;i++){  
                            threads.subThread(i);  
                        }  
                    }  
                }  
                ).start();  
        new Thread(new Runnable(){  
            public void run(){  
                for(int i=1;i<=50;i++){  
                    threads.mainThread(i);  
                }  
            }  
        }).start();  
    }  
}  
  
class MyThread{  
    boolean bShouldSub=true;//标志子线程方法是否被调用  
    public synchronized void subThread(int i){  
        if(!bShouldSub){//若子线程没被调用,即主线程正在运行,所以等待  
            try {  
                this.wait();  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
        for(int j=1;j<=10;j++){  
            System.out.println("sub thread :"+i+",loop : "+j);  
        }  
        bShouldSub=false;//子线程运行完毕  
        this.notify();//唤醒其他线程,即主线程  
    }  
    public synchronized void mainThread(int i){  
        if(bShouldSub){//若子线程正在被调用,所以等待  
            try {  
                this.wait();  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
        for(int j=1;j<=100;j++){  
            System.out.println("main thread :"+i+",loop : "+j);  
        }  
        bShouldSub=true;//主线程调用完毕  
        this.notify();//唤醒子线程  
    }  
}

⑧需求文档和设计文档的区别。

PD(product designer/product director):产品设计或产品负责人,多见于互联网等以产品为中心的行业。
PM(product manager/project manager):产品经理或项目经理。

PD将需求文档给dev(开发人员)

需求文档是根据用户需求转化而来的技术实现需求,需要针对用户提出的产品目标进行细分,总结出具体的每一个功能点,再针对每一个功能点细分为各种不同的操作流程,对每一个操作流程进行技术化定义。也就是说,需求文档是站在用户的角度来描述软件需要实现的功能、各个模块和其重要性、以及业务流程等。

系统设计文档则是站在开发人员的角度来描述软件需要实现的功能、各个模块和其重要性、以及业务流程等。

设计文档分为三部分:总体设计、概要设计、详细设计。

总体设计:设计阶段的目标主要是对待开发系统的构架进行分析和设计,并建立系统构架的基线,梳理业务逻辑且抓住核心需求,设计稳定可扩展的业务系统,评估业务开发周期和开发成本,有效的规避风险,以便为之后的实施工作提供一个稳定的基础。

概要设计:概要设计的目的是描述系统的每个模块的内部设计,对总体设计和详细设计承担承上启下的作用。概要设计按照结构化设计方法进行设计。结构化设计方法的基本思路是:按照问题域,将软件逐级细化,分解为不必再分解的的模块,每个模块完成一定的功能,为一个或多个父模块服务(即接受调用),也接受一个或多个子模块的服务(即调用子模块)。

详细设计:详细设计阶段就是依据概要设计阶段的分解,设计每个模块内的算法、流程,为每个模块完成的功能进行具体的描述,要把功能描述转变为精确的、结构化的过程描述。详细设计这个阶段,各个模块可以分给不同的人去并行设计。设计者的工作对象是一个模块,根据概要设计赋予的局部任务和对外接口设计并表达出模块的算法、流程、状态转换等内容。这里要注意,如果发现有结构调整(如分解出子模块等)的必要必须返回到概要设计阶段,将调整反应到概要设计文档中,而不能就地解决,不打招呼。详细设计文档最重要的部分是模块的流程图、状态图、局部变量及相应的文字说明等。一个模块对应一篇详细设计文档。

总结:内容基本都一样!只是表现形式不一样!阅读对象不一样!

⑨监控、灰度、降级和回滚。

监控:通过抛出异常,日志监控等。

灰度:黑白名单,访问权限。

降级、回滚:出现问题先降级,如果问题实在太大,则回滚到上一个版本。

⑩在工作过程中遇到的困难。

方案A,解决了什么问题,带了了什么问题。

方案B,解决了什么问题,带来了什么问题。

方案C,

发现新的解决方法,规避解决问题而带来的新问题。

时间上的分配问题。

⑪给你一串字符,逆序输出。

⑫mybatis #和$的区别。

在mybatis中,配置参数要用#,不要用$符号。因为$不安全,容易被sql注入。

一、利用#正常传参和拼接传参

TbBrandMapper.xml中的部分内容:

 <resultMap id="BaseResultMap" type="com.pinyougou.pojo.TbBrand" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="first_char" property="firstChar" jdbcType="VARCHAR" />
</resultMap>

 <select id="selectUser" resultMap="BaseResultMap">
    SELECT 
    	acc.name FROM tb_brand AS acc
    WHERE
        acc.name like #{userName}
</select>
select选中表tb_brand ,表别名为acc,的name和值#{username}相同的pojo。
BaseResultMap如上定义。是对应定义的pojo。

正常传参:

 service层(服务提供者)调用:

BrandServiceImpl.java中的部分内容:

@Autowired
private TbBrandMapper brandMapper; 
@Override
public List<TbBrand> find(String likeString){
TbBrand user = new TbBrand();
user.setName("likeString");
List<TbBrand> list = brandMapper.selectUser(user.getName());
if(list!=null && list.size()>0){
    for (TbBrand u:list) {
    	System.out.println("用户名:"+u.getName());
    }
}else{
        System.out.println("暂无数据");
}

}

web层(服务消费者)调用:

BrandController.java中的部分内容:

@Reference
private BrandService brandService;

@RequestMapping("/find")
	public List<TbBrand> find(@RequestBody LikeString){
		
		return brandService.find(LikeString.getLikeString());
	}

当LikeString.getLikeString()="wangling"

会输出:

用户名:wangling

拼接传参:LikeString.getLikeString()="'wangling' or acc.name = 'songyi' "

会输出:

暂无数据

因为#符号,把{ }后面的整个值当做字符串传输,而数据库没有对应的name值是'wangling' or acc.name = 'songyi'这么一长串。

但$就不一样,会sql注入,当做sql语句处理。

 <resultMap id="BaseResultMap" type="com.pinyougou.pojo.TbBrand" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="first_char" property="firstChar" jdbcType="VARCHAR" />
</resultMap>

 <select id="selectUser" resultMap="BaseResultMap">
    SELECT 
    	acc.name FROM tb_brand AS acc
    WHERE
        acc.name like ${userName}
</select>
select选中表tb_brand ,表别名为acc,的name和值${username}相同的pojo。
BaseResultMap如上定义。是对应定义的pojo。

如果${username}

username为:"wangling"

则输入:

用户名:wangling

如果拼接传输,username为:"'wangling' or acc.name='zhangsan'",且数据库有这两个名字,则会输出:

用户名:wangling

用户名:zhangsan

相当于sql注入了

SELECT acc.name From tb_brand as acc WHERE acc.name like 'wangling' or acc.name='zhangsan'; 

如:order by 需要用${}

⑬编写一个程序,将 a.txt 文件中的单词与 b.txt 文件中的单词交替合并到 c.txt 文件中,a.txt 文件中的单词用回车符分隔,b.txt 文件中用回车或空格进行分隔。

package com.itlss.test;
  
import java.io.File;  
import java.io.FileReader;  
import java.io.FileWriter;  
  
public class MainClass{  
    public static void main(String[] args) throws Exception{  
        FileManager a = new FileManager("d:/a.txt",new char[]{'\n'});  
        FileManager b = new FileManager("d:/b.txt",new char[]{'\n',' '});        
        FileWriter c = new FileWriter("d:/c.txt");  
        //String a = null;说明有一个引用了,但这个引用未指向任何内存空间。a.trim()跑出空指针异常。
        //String a;只定义了一个变量a,没有给它赋值。
        //String a = "";说明有一个引用a,这个引用指向了一个内存空间,这个内存空间存放的是空字符串。a.trim()不会抛出异常。
        //String a = "abc";说明有一个引用a,这个引用指向了一个内存空间,这个内存空间存放的是字符串"abc",a.trim()也不抛出异常。
        String aWord = null;  
        String bWord = null;  
        while((aWord = a.nextWord()) !=null ){  
            c.write(aWord + "\n");  
            bWord = b.nextWord();  
            if(bWord != null)  
                c.write(bWord + "\n");  
        }  
          
        while((bWord = b.nextWord()) != null){  
            c.write(bWord + "\n");  
        }     
        c.close();  
    }  
      
}  
  
  
class FileManager{  
  
    String[] words = null;  
    int pos = 0;  
    public FileManager(String filename,char[] seperators) throws Exception{  
        File f = new File(filename);  
        FileReader reader = new FileReader(f); 
        System.out.println("f.length="+f.length());
        //f.length()表示文件的大小(不是文件的占用空间),字节为单位,转换成int。(int)f.length()
        char[] buf = new char[(int)f.length()];  
        //char是字符型变量,只占用一个字节(两个字位)
		//reader.read(buf)表示:先读文件f,按大小char[(int)f.length()],即字节大小(int)f.length()
		//读取文件f,分块读取文件f。然后将读取的文件放入buf中。因为文件比较小,直接用f.length()
		//此时,len和f.(int)length()值一样。但如果在读大文件时,一般char[] buf = new char[1024];
		//然后循环while(reader.read(buf)!=-1){
		//读取文件
		//}这里文件很小,一次性读取。
        int len = reader.read(buf); 
        System.out.println("len="+len);
        String results = new String(buf,0,len);  
        System.out.println("results="+results);
        String regex = null;  
        if(seperators.length >1 ){  
            regex = "" + seperators[0] + "|" + seperators[1];  
        }else{  
            regex = "" + seperators[0];  
        }  
        words = results.split(regex);  
    }  
      
    public String nextWord(){  
        if(pos == words.length)  
            return null;  
        return words[pos++];  
    }  
  
}

⑭金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一 千零一拾一元整)输出。

package com.hangtianxinxi.interview;
 
import java.text.NumberFormat;
import java.util.HashMap;
 
//金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
public class SimpleMoneyFormat {
 
	public static final String EMPTY = "";
	public static final String ZERO = "零";
	public static final String ONE = "壹";
	public static final String TWO = "贰";
	public static final String THREE = "叁";
	public static final String FOUR = "肆";
	public static final String FIVE = "伍";
	public static final String SIX = "陆";
	public static final String SEVEN = "柒";
	public static final String EIGHT = "捌";
	public static final String NINE = "玖";
	public static final String TEN = "拾";
	public static final String HUNDRED = "佰";
	public static final String THOUSAND = "仟";
	public static final String TEN_THOUSAND = "万";
	public static final String HUNDRED_MILLION = "亿";
	public static final String YUAN = "元";
	public static final String JIAO = "角";
	public static final String FEN = "分";
	public static final String DOT = ".";
	
	private static SimpleMoneyFormat formatter = null;
	private HashMap chineseNumberMap = new HashMap();
	private HashMap chineseMoneyPattern = new HashMap();
	private NumberFormat numberFormat = NumberFormat.getInstance();
	
	private SimpleMoneyFormat(){
		numberFormat.setMaximumFractionDigits(4);
		numberFormat.setMinimumFractionDigits(2);
		numberFormat.setGroupingUsed(false);
		chineseNumberMap.put("0", ZERO);
		chineseNumberMap.put("1", ONE);
		chineseNumberMap.put("2", TWO);
		chineseNumberMap.put("3", THREE);
		chineseNumberMap.put("4", FOUR);
		chineseNumberMap.put("5", FIVE);
		chineseNumberMap.put("6", SIX);
		chineseNumberMap.put("7", SEVEN);
		chineseNumberMap.put("8", EIGHT);
		chineseNumberMap.put("9", NINE);
		chineseNumberMap.put(DOT, DOT);
		
		chineseMoneyPattern.put("1", TEN);
		chineseMoneyPattern.put("2", HUNDRED);
		chineseMoneyPattern.put("3", THOUSAND);
		chineseMoneyPattern.put("4", TEN_THOUSAND);
		chineseMoneyPattern.put("5", TEN);
		chineseMoneyPattern.put("6", HUNDRED);
		chineseMoneyPattern.put("7", THOUSAND);
		chineseMoneyPattern.put("8", HUNDRED_MILLION);
	}
	
	public static SimpleMoneyFormat getInstance(){
		if(formatter == null){
			formatter = new SimpleMoneyFormat();
		}
		return formatter;
	}
	
	public String format(String moneyStr){
		checkPrecision(moneyStr);
		String result;
		result = convertToChineseNumber(moneyStr);
		result = addUnitsToChineseMoneyString(result);
		return result;
	}
	
	public String format(double moneyDouble){
		return format(numberFormat.format(moneyDouble));
	}
	
	public String format(int moneyInt){
		return format(numberFormat.format(moneyInt));
	}
	
	public String format(long moneyLong){
		return format(numberFormat.format(moneyLong));
	}
	
	//所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。这里是多态。
	public String format(Number moneyNum){
		return format(numberFormat.format(moneyNum));
	}
	
	private String convertToChineseNumber(String moneyStr){
		String result;
		StringBuffer cMoneyStringBuffer = new StringBuffer();
		for (int i = 0; i < moneyStr.length(); i++) {
			//moneyStr.substring(i, i+1);i为起始索引(包括),i+1位结束前索引(不包括),注意:i到i+1,不包括i+1结束索引。
			cMoneyStringBuffer.append(chineseNumberMap.get(moneyStr.substring(i, i+1)));
		}
		System.out.println("将阿拉伯数字转换成中文zero、one----nine:"+cMoneyStringBuffer);
		//拾佰仟万亿等都是汉字里面才有的单位,加上它们
		int indexOfDot = cMoneyStringBuffer.indexOf(DOT);
		System.out.println("DOTINDEX"+indexOfDot);
		int moneyPatternCursor = 1;
		for(int i=indexOfDot-1;i>0;i--){
			cMoneyStringBuffer.insert(i,chineseMoneyPattern.get(EMPTY+moneyPatternCursor));
			moneyPatternCursor = moneyPatternCursor == 8?1:moneyPatternCursor+1;
		}
		System.out.println("将阿拉伯数字转换成中文zero、one----nine加上单位个十百千等:"+cMoneyStringBuffer);
		String fractionPat = cMoneyStringBuffer.substring(cMoneyStringBuffer.indexOf("."));
		cMoneyStringBuffer.delete(cMoneyStringBuffer.indexOf("."),cMoneyStringBuffer.length());
		while(cMoneyStringBuffer.indexOf("零拾")!=-1){
			cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零拾"), cMoneyStringBuffer.indexOf("零拾")+2, ZERO);
		}
		while (cMoneyStringBuffer.indexOf("零佰") != -1) {
			cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零佰"), cMoneyStringBuffer.indexOf("零佰") + 2, ZERO);
			}
		while (cMoneyStringBuffer.indexOf("零仟") != -1) {
			cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零仟"), cMoneyStringBuffer.indexOf("零仟") + 2, ZERO);
		}
		while (cMoneyStringBuffer.indexOf("零万") != -1) {
			cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零万"), cMoneyStringBuffer.indexOf("零万") + 2, TEN_THOUSAND);
		}
		while (cMoneyStringBuffer.indexOf("零亿") != -1) {
			cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零亿"), cMoneyStringBuffer.indexOf("零亿") + 2, HUNDRED_MILLION);
		}
		while (cMoneyStringBuffer.indexOf("零零") != -1) {
			cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零零"), cMoneyStringBuffer.indexOf("零零") + 2, ZERO);
		}
		System.out.println("将阿拉伯数字转换成中文zero、one----nine,去零后结果:"+cMoneyStringBuffer);
		if(cMoneyStringBuffer.lastIndexOf(ZERO) == cMoneyStringBuffer.length()-1)
			cMoneyStringBuffer.delete(cMoneyStringBuffer.length()-1, cMoneyStringBuffer.length());
			cMoneyStringBuffer.append(fractionPat);
			result = cMoneyStringBuffer.toString();
		System.out.println("第一次的返回结果:"+result);
		return result;
	}
	
	private String addUnitsToChineseMoneyString(String moneyStr){
		String result;
		StringBuffer cMoneyStringBuffer = new StringBuffer(moneyStr);
		int indexOfDot = cMoneyStringBuffer.indexOf(DOT);
		//把点变成元。
		cMoneyStringBuffer.replace(indexOfDot, indexOfDot + 1, YUAN);
		cMoneyStringBuffer.insert(cMoneyStringBuffer.length() - 1, JIAO);
		cMoneyStringBuffer.insert(cMoneyStringBuffer.length(), FEN);
		if (cMoneyStringBuffer.indexOf("零角零分") != -1)//没有零头,加整
		cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零角零分"), cMoneyStringBuffer.length(), "整");
		else
		if (cMoneyStringBuffer.indexOf("零分") != -1)//没有零分,加整
		cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零分"), cMoneyStringBuffer.length(), "整");
		else {
		if(cMoneyStringBuffer.indexOf("零角")!=-1)
		//cMoneyStringBuffer.delete(cMoneyStringBuffer.indexOf("零角"),cMoneyStringBuffer.indexOf("零角")+2);
		// tmpBuffer.append("整");
		cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零角"),cMoneyStringBuffer.length(), "整");
		}
		result = cMoneyStringBuffer.toString();
		return result;
	}
	
	private void checkPrecision(String moneyStr){
		int fractionDigits = moneyStr.length()-moneyStr.indexOf(DOT)-1;
		if(fractionDigits>2)
			throw new RuntimeException("金额"+moneyStr+"的小数位多于两位。");//精度不能比分低
	}
	
	public static void main(String [] args){
		System.out.println(getInstance().format(new Double(1001034)));
	}
	
}

⑮dao层需要加入依赖pojo层
interface层需要加入依赖pojo层

service层(服务提供者)需要加入依赖dao层和interface层
web层(服务消费者)需要加入依赖interface层
 

⑯mybatis和hibernate/JPA的区别.

ORM:object relationship mapping:对象关系映射

JPA(对象持久化的API):规范,各大ORM框架实现这个规范。可以自动建表。

Hibernate:是完整的ORM框架,不需要我们写sql,框架比较重,学习成本比较高,性能不好控制,功能强大且文档丰富。

Mybatis:不是完整的ORM框架,程序员需要自己去写全部的SQL,轻量级框架,学习成本低,性能好控制。不能自动建表。

⑰IOC(inversion of controll)控制反转、DI(dependency injection)依赖注入

和依赖倒置(dependency inversion principle)

IOC(inversion of controll)控制反转:将控制权反转。以前是应用程序的对象,new一个对象,直接控制对象。现在是应用程序的容器通过依赖注入DI,直接控制对象。控制权由应用程序的对象反转给应用程序的容器。

DI(dependency injecton)依赖注入:应用程序需要IOC(inversion of controll)控制反转容器,注入应用程序依赖的对象及对象包含的资源数据。

依赖倒置:应用程序依赖于抽象接口,而不是依赖于具体实现。为了消除两个模块之间的依赖关系,应该在两个模块之间定义抽象接口。

发布了122 篇原创文章 · 获赞 1 · 访问量 3555

猜你喜欢

转载自blog.csdn.net/lbh19630726/article/details/103788042
今日推荐