java后台实现支付宝支付接口、支付宝订单查询接口 前端为APP

技术标签: 支付类  java后台支付宝接口实现详细过程  java后台支付宝接口实现  

       最近项目APP需要接入微信、支付宝支付功能,在分配开发任务时,听说微信支付接口比支付宝支付接口要难实现,由于我开发经验不是那么丰富(现工作经验1年半)且未接触过支付接口开发,组里刚好又有支付接口的老司机,所以很自然把简单的支付宝接口开发任务交给了我,看来开发组的组长还是很好人的嘛.....,废话就不多说了,我们开始吧!

实现支付宝接口详细过程

1.去支付宝官网申请公司企业账号并开通一个应用,在应用里签约APP支付功能

具体的申请截图步骤,在这里我就不详细说了,因为这不是文章的重点,可参考支付宝官网

经过这一步,我们可以得过开发中需要用到的几个参数

①商户appid  ②商户公钥、私钥  ③支付宝公钥  ④支付宝网关地址

解释一下这几个参数:

1.商户appid是识别商户的唯一ID,是让支付宝识别,我们到底是哪一个商户,这样支付宝就能识别商户对应的账号、用户号、收款账号...等等一系列信息。

2.商户公钥、私钥以及支付宝公钥这3个参数是对商户系统与支付宝进行信息交互的数字签名用的,相信各位大学里也有学过关于数字签名的一些知识,在这里,我就简单说一下我理解的过程:首先是商户系统需要给支付宝发送信息(支付、查询等等....),涉及钱方面,咱们当前要谨慎一点对吧,所以我们需要对发送之前的信息加把锁(用商户私钥进行签名),然后再发送给支付宝。支付宝收到商户发送的信息之后,发现上了把锁,那肯定得要一把钥匙(商户公钥)来解锁对吧,所以商户在跟支付宝签约APP支付功能的时候,就得把这把钥匙上传给支付宝了,支付宝就可以用商户的公钥进行解锁了。反过来也是一样,支付宝需要发送信息给商户信息,先用支付宝的私钥进行签名,再发送给商户系统,商户系统收到支付宝反馈过来的信息后,再用支付宝的公钥进行解密。在这里我们并没有用到支付宝的私钥,所以我们并不需要得到支付宝的私钥。这里放一个生成私钥公钥的支付宝官方工具

3.支付宝网关地址,是用来配置发送给支付宝的网关地址的。

2.将支付宝的SDK集成到项目系统里

支付宝的SDK指的就是支付宝提供的工具Jar包给我们开发者,SDK封装了大量的基础功能,使我们可以快速开发支付宝接口。这也是我在前面说的比微信支付接口更容易实现的原因。获取支付宝SDK地址:支付宝SDK下载地址,这里我选择JAVA的SDK。下载解压后的SDK得到:


alipay-sdk-java20180122110032.jar、commons-logging-1.1.1.jar是我们需要导入到项目里的,因为项目后台的大致的架构是maven+springBoot+jpa,所以我们需要从maven里导入jar包,首先是导入commons-logging-1.1.1.jar,不用多说,咱直接在pom.xml里加上:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.1</version>
</dependency>

然后是alipay-sdk-java20180122110032.jar,如果你也像上面一样直接加入到pom.xml,会发现,咦,怎么一直下载不下来。当然alipy的包在线上的maven仓库并没有,所以我们需要导入到本地的maven仓库。前提是配置好maven的环境变量,将包放在G:\alipay\sdk下,然后打开dos窗口,cd进入到G:\alipay\sdk下,执行maven如下命令:

 mvn install:install-file -DgroupId=com.alipay -DartifactId=sdk-java -Dversion=20180122110032 -Dpackaging=jar -Dfile=alipay-sdk-java20180122110032.jar

导入成功后,在项目的pom.xml里继续添加

<!-- 支付宝SDK -->
<dependency>
    <groupId>com.alipay</groupId>
    <artifactId>sdk-java</artifactId>
    <version>20180122110032</version>
</dependency>

到此,我们就顺利把支付宝SDK集成到项目里,是不是有点小兴奋,我们很快可以开发了!

3.看支付宝提供的API和网上各位牛人总结的经验,后台使用支付宝的SDK与支付宝进行交互

先看一下支付宝支付流程的图:


    首先,我们来理一理开发的思路,按照我当前项目的需求,关于支付这一块大概操作流程是:用户在APP上选好要购买的商品,点击“立即购买”,跳转到订单详细页面。选择支付方式,点击“确定支付”跳转到支付宝APP,付款完成后,跳转回APP,完成支付。这个过程,当用户点击“确定支付”时,APP需要调用商户后台接口。

    这时候就是我们所需要做的事情:先是生成商户系统一笔未支付的订单,获得商户订单ID(商户系统生成)和订单的一些其他信息,然后再调用支付宝的SDK提供的数字签名方法,将需要传给支付宝的信息进行加签,然后把加签后的字符串返回给APP。APP拉起支付宝APP,再把这个加签的字符串传给支付宝,完成支付。APP接收到同步通知后,还需要再次调用商户后台的接口(虽然同步通知也有付款情况,但需要以后台通知为准),校验订单最终的付款情况。按照支付宝API上所说,当完成支付后,支付宝会做2个操作,一个是同步返回信息给APP,一个是异步通知商户后台返回支付状态等信息,并且最终的支付结果是以异步通知为准。所以我们还需要考虑到一点,就是当用户支付成功之后,商户系统暂时没有接收到支付宝的异步通知时。我们需要拿着这个商户订单ID主动调用SDK支付宝的查询接口,去获取该订单的支付情况,并最终返回给APP。这个查询的接口应该是给APP收到同步通知后,请求商户系统后台进行校验的时候调用的。

根据我们上面思考所得,后台只需要对外提供3个接口即可

1.用户点击“立即购买”时调用商户后台接口,后台返回加签后的订单信息字符串

2.在支付完成之后,支付宝异步通知商户后台订单的付款情况

3.在支付完成之后,跳转回APP时,APP调用商户后台进行最终付款校验


想通想明白之后,终于接一下我们要敲代码了,哈哈哈哈

首先,我们来准备一下需要传给支付宝SDK的公共基本参数,我把参数放到一个单独的类里,你也可以放到数据库里,代码如下:

public class AlipayConfig {
    // 1.商户appid
    //public static String APPID = "2017...";    
    
    //2.私钥 pkcs8格式的
    public static String RSA_PRIVATE_KEY ="MIIEwAIBADANBg.....";
    
    // 3.支付宝公钥
    public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkq.....";
    
    // 4.服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String notify_url = "http://www.xxx.com/alipay/notify_url.do";
    
     //5.页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
    public static String return_url = "http://www.xxx.com/alipay/return_url.do";
    
    // 6.请求支付宝的网关地址
    public static String URL = "https://openapi.alipay.com/gateway.do";    
    
    // 7.编码
    public static String CHARSET = "UTF-8";
    
    // 8.返回格式
    public static String FORMAT = "json";
    
    // 9.加密类型
    public static String SIGNTYPE = "RSA2";
    
}


1.实现第一个接口:用户点击“立即购买”时调用商户后台接口,后台返回加签后的订单信息字符串。我把主要的处理逻辑写在Service层了,Controller层直接调用就可以,这里就不放Controller层的代码了

生成商户订单的代码,我就不放了,这个根据各自的业务需求来做,生成后订单之后,把订单信息传进来该方法进行处理,返回加签后的字符串,直接返回给APP即可,代码如下:

/**
	 * 获取支付宝加签后台的订单信息字符串
	 * 
	 * @param request
	 * @return
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String getAliPayOrderStr(OrderTest orderTest) {
		
		//最终返回加签之后的,app需要传给支付宝app的订单信息字符串	
		String orderString = "";
		logger.info("==================支付宝下单,商户订单号为:"+orderTest.getOutTradeNo());

		//创建商户支付宝订单(因为需要记录每次支付宝支付的记录信息,单独存一个表跟商户订单表关联,以便以后查证)
		AlipaymentOrder alipaymentOrder=new AlipaymentOrder();
		alipaymentOrder.setClubOrderId(orderTest.getId().toString());//商家订单主键
		alipaymentOrder.setOutTradeNo(orderTest.getOutTradeNo());//商户订单号
		alipaymentOrder.setTradeStatus((byte) 0);//交易状态
		alipaymentOrder.setTotalAmount(Double.parseDouble(orderTest.getTotalAmount()));//订单金额
		alipaymentOrder.setReceiptAmount(0.00);//实收金额
		alipaymentOrder.setInvoiceAmount(0.00);//开票金额
		alipaymentOrder.setBuyerPayAmount(0.00);//付款金额
		alipaymentOrder.setRefundFee(0.00);	//总退款金额
				
		try{	
		//实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息
                AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, 
        		        AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, 
        		        AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
        
                //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay 
                AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
        
                //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
                AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        
                //业务参数传入,可以传很多,参考API
                //model.setPassbackParams(URLEncoder.encode(request.getBody().toString())); //公用参数(附加数据)
                model.setBody(orderTest.getBody());                       //对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
                model.setSubject(orderTest.getSubjecy());                 //商品名称
                model.setOutTradeNo(orderTest.getOutTradeNo());           //商户订单号(自动生成)
               // model.setTimeoutExpress("30m");     			  //交易超时时间
                model.setTotalAmount(orderTest.getTotalAmount());         //支付金额
                model.setProductCode("QUICK_MSECURITY_PAY");        	  //销售产品码(固定值)
                ali_request.setBizModel(model);  
                logger.info("====================异步通知的地址为:"+alipayment.getNotifyUrl());
                ali_request.setNotifyUrl(AlipayConfig.notify_url);        //异步回调地址(后台)
                ali_request.setReturnUrl(AlipayConfig.return_url);	    //同步回调地址(APP)
        
                // 这里和普通的接口调用不同,使用的是sdkExecute
		AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request); //返回支付宝订单信息(预处理)
		orderString=alipayTradeAppPayResponse.getBody();//就是orderString 可以直接给APP请求,无需再做处理。
		this.createAlipayMentOrder(alipaymentOrder);//创建新的商户支付宝订单
		
		} catch (AlipayApiException e) {
			e.printStackTrace();
			logger.info("与支付宝交互出错,未能生成订单,请检查代码!");
		} 

        return orderString;
	}


2.实现第二个接口:在支付完成之后,支付宝异步通知商户后台订单的付款情况,这个是支付宝每隔一段时间来访问一次的接口,直到你返回success,才会停止访问,这里我分了2个地方进行调用

        /**
	 * 支付宝支付成功后.异步请求该接口
	 * @param request
	 * @return
	 * @throws IOException
	 */  
	@RequestMapping(value="/notify_url",method=RequestMethod.POST)
	@ResponseBody
	public String notify(HttpServletRequest request,HttpServletResponse response) throws IOException {  
		logger.info("==================支付宝异步返回支付结果开始");
		//1.从支付宝回调的request域中取值	
		//获取支付宝返回的参数集合
        Map<String, String[]> aliParams = request.getParameterMap();  
        //用以存放转化后的参数集合
        Map<String, String> conversionParams = new HashMap<String, String>();  
	    for (Iterator<String> iter = aliParams.keySet().iterator(); iter.hasNext();) {  
	        String key = iter.next();  
	        String[] values = aliParams.get(key);  
	        String valueStr = "";  
	        for (int i = 0; i < values.length; i++) {  
	            valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";  
	        }  
	        // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化  
	        // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "uft-8");  
	        conversionParams.put(key, valueStr);  
	    }  	
	    logger.info("==================返回参数集合:"+conversionParams);
	   String status=alipayMentOrderService.notify(conversionParams);
	   return status;
	}


 /**
	 * 支付宝异步请求逻辑处理
	 * @param request
	 * @return
	 * @throws IOException
	 */ 
	public String notify(Map<String, String> conversionParams){
		
		logger.info("==================支付宝异步请求逻辑处理");
			
		 //签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
	    boolean signVerified = false;  	 
	    
	    try {  
	        //调用SDK验证签名
	        signVerified = AlipaySignature.rsaCheckV1(conversionParams, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE); 
	        
	    } catch (AlipayApiException e) {  
	    	logger.info("==================验签失败 !");	
	        e.printStackTrace();         
	    }  	 
	    
	    //对验签进行处理
	    if (signVerified) {
	    	//验签通过  	    	
	    	//获取需要保存的数据
	    	    String appId=conversionParams.get("app_id");//支付宝分配给开发者的应用Id
		    String notifyTime=conversionParams.get("notify_time");//通知时间:yyyy-MM-dd HH:mm:ss
		    String gmtCreate=conversionParams.get("gmt_create");//交易创建时间:yyyy-MM-dd HH:mm:ss
		    String gmtPayment=conversionParams.get("gmt_payment");//交易付款时间
		    String gmtRefund=conversionParams.get("gmt_refund");//交易退款时间
		    String gmtClose=conversionParams.get("gmt_close");//交易结束时间
		    String tradeNo=conversionParams.get("trade_no");//支付宝的交易号
		    String outTradeNo = conversionParams.get("out_trade_no");//获取商户之前传给支付宝的订单号(商户系统的唯一订单号)
		    String outBizNo=conversionParams.get("out_biz_no");//商户业务号(商户业务ID,主要是退款通知中返回退款申请的流水号)
		    String buyerLogonId=conversionParams.get("buyer_logon_id");//买家支付宝账号
		    String sellerId=conversionParams.get("seller_id");//卖家支付宝用户号
		    String sellerEmail=conversionParams.get("seller_email");//卖家支付宝账号
		    String totalAmount=conversionParams.get("total_amount");//订单金额:本次交易支付的订单金额,单位为人民币(元)
		    String receiptAmount=conversionParams.get("receipt_amount");//实收金额:商家在交易中实际收到的款项,单位为元
		    String invoiceAmount=conversionParams.get("invoice_amount");//开票金额:用户在交易中支付的可开发票的金额
		    String buyerPayAmount=conversionParams.get("buyer_pay_amount");//付款金额:用户在交易中支付的金额		  
		    String tradeStatus = conversionParams.get("trade_status");// 获取交易状态 
		    
		    //支付宝官方建议校验的值(out_trade_no、total_amount、sellerId、app_id)
		    AlipaymentOrder alipaymentOrder=this.selectByOutTradeNo(outTradeNo); 	
		  
		    if(alipaymentOrder!=null&&totalAmount.equals(alipaymentOrder.getTotalAmount().toString())&&AlipayConfig.APPID.equals(appId)){
			    //修改数据库支付宝订单表(因为要保存每次支付宝返回的信息到数据库里,以便以后查证)
			    alipaymentOrder.setNotifyTime(dateFormat(notifyTime));
			    alipaymentOrder.setGmtCreate(dateFormat(gmtCreate));
			    alipaymentOrder.setGmtPayment(dateFormat(gmtPayment));
			    alipaymentOrder.setGmtRefund(dateFormat(gmtRefund));
			    alipaymentOrder.setGmtClose(dateFormat(gmtClose));
			    alipaymentOrder.setTradeNo(tradeNo);
			    alipaymentOrder.setOutBizNo(outBizNo);
			    alipaymentOrder.setBuyerLogonId(buyerLogonId);
			    alipaymentOrder.setSellerId(sellerId);
			    alipaymentOrder.setSellerEmail(sellerEmail);
			    alipaymentOrder.setTotalAmount(Double.parseDouble(totalAmount));
			    alipaymentOrder.setReceiptAmount(Double.parseDouble(receiptAmount));
			    alipaymentOrder.setInvoiceAmount(Double.parseDouble(invoiceAmount));
			    alipaymentOrder.setBuyerPayAmount(Double.parseDouble(buyerPayAmount));
			    switch (tradeStatus) // 判断交易结果
	                    {
	                    case "TRADE_FINISHED": // 交易结束并不可退款
	            	        alipaymentOrder.setTradeStatus((byte) 3);
	                        break;
	                    case "TRADE_SUCCESS": // 交易支付成功
	            	        alipaymentOrder.setTradeStatus((byte) 2);	            	  
	                        break;
	                    case "TRADE_CLOSED": // 未付款交易超时关闭或支付完成后全额退款
	            	        alipaymentOrder.setTradeStatus((byte) 1);
	                        break;
	                    case "WAIT_BUYER_PAY": // 交易创建并等待买家付款
	            	        alipaymentOrder.setTradeStatus((byte) 0);
	                        break;
	                    default:
	                        break;
	                    }
			    int returnResult=this.updateByPrimaryKey(alipaymentOrder);    //更新交易表中状态
			    		    			    
		        if(tradeStatus.equals("TRADE_SUCCESS")) {    //只处理支付成功的订单: 修改交易表状态,支付成功
		          
		            if(returnResult>0){
		                 return "success";
		            }else{
		                 return "fail";
		            }
		        }else{
		            return "fail";
		        }
		    	
		    }else{
		    	logger.info("==================支付宝官方建议校验的值(out_trade_no、total_amount、sellerId、app_id),不一致!返回fail");
		    	return"fail";
		    }

	    } else {  //验签不通过   
	    	logger.info("==================验签不通过 !");
	        return "fail";
	    }
		
	}


3.实现第三个接口:在支付完成之后,跳转回APP时,APP调用商户后台进行最终付款校验。我把主要的处理逻辑写在Service层了,Controller层直接调用就可以,这里就不放Controller层的代码了。

/**
	 * 向支付宝发起订单查询请求
	 * @param request
	 * @return
	 * @throws IOException
	 */ 
	@Override
	public Byte checkAlipay(String outTradeNo) {
		logger.info("==================向支付宝发起查询,查询商户订单号为:"+outTradeNo);
		
		try {
		//实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型)
                AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, 
        		AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, 
        		AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
		AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
		alipayTradeQueryRequest.setBizContent("{" +
		"\"out_trade_no\":\""+outTradeNo+"\"" +
		"}");
		AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(alipayTradeQueryRequest);	
		if(alipayTradeQueryResponse.isSuccess()){
				
		    AlipaymentOrder alipaymentOrder=this.selectByOutTradeNo(outTradeNo);
		    //修改数据库支付宝订单表
		    alipaymentOrder.setTradeNo(alipayTradeQueryResponse.getTradeNo());
		    alipaymentOrder.setBuyerLogonId(alipayTradeQueryResponse.getBuyerLogonId());
		    alipaymentOrder.setTotalAmount(Double.parseDouble(alipayTradeQueryResponse.getTotalAmount()));
		    alipaymentOrder.setReceiptAmount(Double.parseDouble(alipayTradeQueryResponse.getReceiptAmount()));
		    alipaymentOrder.setInvoiceAmount(Double.parseDouble(alipayTradeQueryResponse.getInvoiceAmount()));
		    alipaymentOrder.setBuyerPayAmount(Double.parseDouble(alipayTradeQueryResponse.getBuyerPayAmount()));
		    switch (alipayTradeQueryResponse.getTradeStatus()) // 判断交易结果
                    {
                    case "TRADE_FINISHED": // 交易结束并不可退款
            	        alipaymentOrder.setTradeStatus((byte) 3);
                        break;
                    case "TRADE_SUCCESS": // 交易支付成功
            	        alipaymentOrder.setTradeStatus((byte) 2);          	
                        break;
                    case "TRADE_CLOSED": // 未付款交易超时关闭或支付完成后全额退款
            	        alipaymentOrder.setTradeStatus((byte) 1);          	
                        break;
                    case "WAIT_BUYER_PAY": // 交易创建并等待买家付款
            	        alipaymentOrder.setTradeStatus((byte) 0);
                        break;
                    default:
                        break;
                    }
		    this.updateByPrimaryKey(alipaymentOrder); //更新表记录
		    return alipaymentOrder.getTradeStatus();
		} else {
			logger.info("==================调用支付宝查询接口失败!");
		}
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 0;
	}

至此,代码已经上完了,里面可能涉及部分业务代码,如果各位需要拿代码,需要把业务代码换成自己所需要的。


建议:可以边看API边进行开发,主要是看我们需要给支付传什么参数,支付宝可以给我们传什么参数,不然没看清除,你会多很多坑要踩的,亲试过。

感觉太少图片了,这里给几张API的图片。。你们也可以自己去看 一些支付宝API



4.关于测试的一些事

支付宝有提供沙箱环境进行测试所使用,见支付宝沙箱调试指南

但是楼主比较有米,直接用真实环境进行测试,其实测一次0.01元也是挺贵的吧,前提是你的电脑必须访问外网和能够被外网所访问,建议可以找个内网穿透的工具。

写了一整个下午,好累啊,本人新手,如有错误,请各位大神指教,希望对大家有用!!!!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Ouyzc/article/details/79551714

智能推荐

python 堆栈溢出_PWN简单堆栈溢出漏洞利用(一) | kTWO-个人博客_weixin_39652646的博客-程序员宅基地

摘要本文将详细讲述PWN二进制漏洞中简单的堆栈利用,本文将从原理开始讲述,然后层层深入,让读者从理解到动手操作,能够跟着教程完成所有操作。0x01 环境和程序准备安装有pwntools的kali Linux,安装教程可参考上一篇文章。gdb-peda工具,这个是gdb的插件这个可以百度一下安装和使用教程。IDA反汇编工具,可自行百度下载和学习使用方法,本文只做简单介绍。一个Linxu X86的含有...

matlab隐含层个数设置,BP神经网络隐藏层节点数如何确定_weixin_39671374的博客-程序员宅基地

新人求教:本人的输入矩阵为p,每一列为一个特征向量,每一行为一个样本,现在我想按列归一化,我自己写的用for循环逐列归一化,但是发现输出反归一化还原时不好处理,求老师们教教有没有一些函数的使用技巧能按列归一化后而且能使得能方便地反归一化得到输出。网络输入p、输出t见下:p =[ 695.50 1.60 2.06 38.00 31....

java 接口 protected_为什么类和接口不能使用private和protected?接口的方法不能使用private、protected、default..._努力提高做饭水平的博客-程序员宅基地

对于java程序员来说,java的访问权限修饰词public、protected、default、private的区别和使用肯定都不是问题,这里也不再啰嗦了,反正度娘一搜就一大把。最近在整理java core的培训资料时,想到了几个关于权限修饰词的问题:为什么类和接口(不考虑内部类和接口)不能使用private和protected修饰词,只能是public和default?为什么接口的方法不能是p...

计算机基础知识 填空,计算机基础知识填空题_宇较瘦的博客-程序员宅基地

计算机基础知识填空题(一)1.计算机的主机是由____和____组成。解答:计算机的硬件系统由中央处理器、存储器、输入设备和输出设备等部分组成。中央处理器和内存储器合起来称为主机。本题正确答案为中央处理器和内存储器。2.CPU是由____和____组成的。解答:CPU又称中央处理器,它主要由运算器和控制器组成。运算器的主要功能是负责算术运算和逻辑运算;控制器的主要功能是控制计算机各部件协同动作。本...

android 自定义textview自己绘制文字,Android自定义View之继承TextView绘制背景_平仄仄的博客-程序员宅基地

本文实例为大家分享了TextView绘制背景的方法,供大家参考,具体内容如下效果:实现流程:1.初始化:对画笔进行设置mPaintIn = new Paint();mPaintIn.setAntiAlias(true);mPaintIn.setDither(true);mPaintIn.setStyle(Paint.Style.FILL);mPaintIn.setColor(getResource...

cilium插件测试_[译] 基于 Envoy、Cilium 和 eBPF 实现透明的混沌测试(2019)_隔壁王医生的博客-程序员宅基地

[译] 基于 Envoy、Cilium 和 eBPF 实现透明的混沌测试(2019)Published at 2019-06-02 | Last Update 2019-06-04译者序本文内容来自 2019 年的一个技术分享 Transparent Chaos Testing with Envoy, Ciliumand eBPF,演讲嘉宾是 Cilium 项目的创始人和核心开发者,演讲为英文。本...

随便推点

python中aorb是什么意思_ABtest的python实现_weixin_39580682的博客-程序员宅基地

一、数据来源链接:https://pan.baidu.com/s/1M-xOK_hR7MoAgbZWATls0Q​pan.baidu.com提取码: g2vw本数据集包含2017年1月1日至2017年1月24日共24天的一家教育公司网站落地页的访问量详情,公司网站随机刷新落地页A—访问课程资料或B—开始免费试学这两个落地页,数据包括用户ID、访问时间、访问页面组别、落地页类型和是否转化。数据集共有...

建堆(堆化)与堆排的时间复杂度和空间复杂度的推导及TopK问题_倚心的博客-程序员宅基地_建堆的时间复杂度和空间复杂度

一:建堆第一种情况:时间复杂度O(logn)若左右子树恰好都是小堆,如何建小堆呢?算法:向下调整算法1. 选出孩子中小的那一个a)小的孩子跟父亲相比,比父亲小则与父亲交换,并把原来孩子的位置当成父亲的新位置继续往下调整,直到parent走到叶子节点b)若比父亲大则不需要处理,调整完成,整个树已经是小堆。//向下调整算法void Swap(int* a, int* b){ int tmp = *a; *a = *b; *b = tmp;}void AdjustDown

【神经网络 隐含层节点数的设置】如何设置神经网络隐藏层 的神经元个数_shang_bo_liang的博客-程序员宅基地_神经网络隐含层的设置

当训练集确定之后,输入层结点数和输出层结点数随之而确定,首先遇到的一个十分重要而又困难的问题是如何优化隐层结点数和隐层数。实验表明,如果隐层结点数过少,网络不能具有必要的学习能力和信息处理能力。反之,若过多,不仅会大大增加网络结构的复杂性(这一点对硬件实现的网络尤其重要),网络在学习过程中更易陷入局部极小点,而且会使网络的学习速度变得很慢。隐层结点数的选择问题一直受到神经网络研究工作者的高度重视。方法1: fangfaGorman指出隐层结点数s与模式数N的关系是:s=log2N; 方法二: K..

比DES加密更安全的算法——3DES加密算法_山楂树之恋的博客-程序员宅基地_3des加密算法安全吗

http://blog.csdn.net/zhaokaiqiang1992/article/details/41093099比DES加密更安全的算法——3DES加密算法标签: des3des2014-11-13 23:32 3513人阅读 评论(0) 收藏 举报 分类:Android常见工具类(5) 版

神经网络隐藏层数和节点数_kyh_0914的博客-程序员宅基地_神经网络层数和节点数

输入层和输出层的节点数量很容易得到。输入层的神经元数量等于待处理数据中输入变量的数量,输出层的神经元的数量等于与每个输入关联的输出的数量。但是真正的困难之处在于确定合适的隐藏层及其神经元的数量。

推荐文章

热门文章

相关标签