我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Feign的请求和响应日志方式是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Feign的请求和响应日志方式是什么

这篇文章主要介绍了Feign的请求和响应日志方式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Feign的请求和响应日志方式是什么文章都会有所收获,下面我们一起来看看吧。

1、项目里定义FeignClient接口

package com.example.demo.feign;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;@FeignClient(name = "deom", url = "https://www.baidu.com")public interface FeignDemo {    @GetMapping("/")    String test();}

2、单个FeignClient接口开启日志

在 application.yml 里指定Feign接口日志级别为DEBUG,类型为FULL:

注:com.example.demo.feign.FeignDemo就是上面定义的FeignClient接口

logging:  level:    com.example.demo.feign.FeignDemo: debug# 下面的配置,也可以写代码代替# @Bean# public Logger.Level level() { return Logger.Level.FULL; }feign:  client:    config:      default:        loggerLevel: full

OK了,重启项目,调用 FeignDemo.test() 方法后,会输出如下日志:

2020-10-13 11:46:24.161 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] ---> GET https://www.baidu.com HTTP/1.1
2020-10-13 11:46:24.162 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] ---> END HTTP (0-byte body)
2020-10-13 11:46:24.255 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] <--- HTTP/1.1 200 OK (93ms)
2020-10-13 11:46:24.255 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] content-length: 2443
2020-10-13 11:46:24.255 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] content-type: text/html
2020-10-13 11:46:24.256 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] date: Tue, 13 Oct 2020 03:46:24 GMT
2020-10-13 11:46:24.256 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] server: bfe
2020-10-13 11:46:24.256 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] 
2020-10-13 11:46:24.257 DEBUG 20824 --- [nio-8080-exec-4] com.example.demo.feign.FeignDemo         : [FeignDemo#test] <!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true class="lazy" data-src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=https://file.lsjlt.com/upload/202306/28/2lmqiwr140b.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="https://file.lsjlt.com/upload/202306/28/2lmqiwr140b.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');
                </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img class="lazy" data-src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

3、所有FeignClient接口 开启日志

上面的方法,只能开启单个FeignClient接口,如果项目里有10个接口,那么要在yml里配置10项,而且以后添加新的FeignClient,还要记得去修改yml配置,太麻烦。

所以,下面是开启所有FeignClient接口日志的配置:

3.1、修改FeignConfiguration

自定义feign.Logger,如下:

package com.example.demo.cacheDemo;import feign.slf4j.Slf4jLogger;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class FeignConfiguration {    @Bean    public feign.Logger logger() {        return new Slf4jLogger();    }}

3.2、还是修改 application.yml 配置

logging:  level:    # 删除具体的FeignClient接口配置,只保留这一个就好了    feign.Logger: debug# 也可以写代码代替# @Bean# public Logger.Level level() { return Logger.Level.FULL; }feign:  client:    config:      default:        loggerLevel: full

2.3、OK了,此时项目里

不管新增多少个 FeignClient,都会输出日志。

4、重写FeignClient输出日志

根据上面输出的日志,可以看到是多条INFO日志,在并发时,很有可能会互相干扰,而且格式也无法调整。

我们知道,Feign默认情况下,是使用 feign.Client.Default 发起http请求;

我们可以重写Client,并注入Bean来替换掉 feign.Client.Default,从而实现日志记录,当然也可以做其它任意事情了,比如添加Header。下面是注入Bean的代码:

// 默认不注入,如果yml配置里有 logging.level.beinet.cn.demostudy.MyClient 才注入@Bean@ConditionalOnProperty("logging.level.beinet.cn.demostudy.MyClient")MyClient getClient() throws NoSuchAlgorithmException, KeyManagementException {    // 忽略SSL校验    SSLContext ctx = SSLContext.getInstance("SSL");    X509TrustManager tm = new X509TrustManager() {        @Override        public void checkClientTrusted(X509Certificate[] chain, String authType) {        }        @Override        public void checkServerTrusted(X509Certificate[] chain, String authType) {        }        @Override        public X509Certificate[] getAcceptedIssuers() {            return null;        }    };    ctx.init(null, new TrustManager[]{tm}, null);    return new MyClient(ctx.getSocketFactory(), (hostname, sslSession) -> true);}

下面是重写的Client完整代码:

package beinet.cn.demostudy;import feign.Client;import feign.Request;import feign.Response;import lombok.extern.slf4j.Slf4j;import org.springframework.util.StreamUtils;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLSocketFactory;import java.io.*;import java.util.Collection;import java.util.Map;@Slf4jpublic class MyClient extends Client.Default {    public MyClient(SSLSocketFactory socketFactory, HostnameVerifier hostnameVerifier) {        super(socketFactory, hostnameVerifier);    }    @Override    public Response execute(Request request, Request.Options options) throws IOException {        StringBuilder sb = new StringBuilder("[log started]\r\n");        sb.append(request.httpMethod()).append(" ").append(request.url()).append("\r\n");        CombineHeaders(sb, request.headers()); // 请求Header        CombineBody(sb, request.body());        long costTime = -1;        Exception exception = null;        BufferingFeignClientResponse response = null;        long begin = System.currentTimeMillis();        try {            response = new BufferingFeignClientResponse(super.execute(request, options));            costTime = (System.currentTimeMillis() - begin);        } catch (Exception exp) {            costTime = (System.currentTimeMillis() - begin);            exception = exp;            throw exp;        } finally {            sb.append("\r\nResponse cost time(ms): ").append(String.valueOf(costTime));            if (response != null)                sb.append("  status: ").append(response.status());            sb.append("\r\n");            if (response != null) {                CombineHeaders(sb, response.headers()); // 响应Header                sb.append("Body:\r\n").append(response.body()).append("\r\n");            }            if (exception != null) {                sb.append("Exception:\r\n  ").append(exception.getMessage()).append("\r\n");            }            sb.append("\r\n[log ended]");            log.debug(sb.toString());        }        Response ret = response.getResponse().toBuilder()                .body(response.getBody(),                        response.getResponse().body().length()).build();        response.close();        return ret;    }    private static void CombineHeaders(StringBuilder sb, Map<String, Collection<String>> headers) {        if (headers != null && !headers.isEmpty()) {            sb.append("Headers:\r\n");            for (Map.Entry<String, Collection<String>> ob : headers.entrySet()) {                for (String val : ob.getValue()) {                    sb.append("  ").append(ob.getKey()).append(": ").append(val).append("\r\n");                }            }        }    }    private static void CombineBody(StringBuilder sb, byte[] body) {        if (body == null || body.length <= 0)            return;        sb.append("Body:\r\n").append(new String(body)).append("\r\n");    }    static final class BufferingFeignClientResponse implements Closeable {        private Response response;        private byte[] body;        private BufferingFeignClientResponse(Response response) {            this.response = response;        }        private Response getResponse() {            return this.response;        }        private int status() {            return this.response.status();        }        private Map<String, Collection<String>> headers() {            return this.response.headers();        }        private String body() throws IOException {            StringBuilder sb = new StringBuilder();            try (InputStreamReader reader = new InputStreamReader(getBody())) {                char[] tmp = new char[1024];                int len;                while ((len = reader.read(tmp, 0, tmp.length)) != -1) {                    sb.append(new String(tmp, 0, len));                }            }            return sb.toString();        }        private InputStream getBody() throws IOException {            if (this.body == null) {                this.body = StreamUtils.copyToByteArray(this.response.body().asInputStream());            }            return new ByteArrayInputStream(this.body);        }        @Override        public void close() {            this.response.close();        }    }}

输出日志示例:

2020-10-15 16:48:26.081 DEBUG 15664 --- [           main] beinet.cn.demostudy.MyClient             : [log started]
POST https://www.baidu.com?flg=3
Headers:
  Content-Length: 14
  Content-Type: text/plain;charset=UTF-8
Body:
abcde我是ddd

Response cost time(ms): 207  status: 200
Headers:
  content-length: 2443
  content-type: text/html
  date: Thu, 15 Oct 2020 08:48:27 GMT
  server: bfe
Body:
<!DOCTYPE html>百度的html</html>

5、使用Aspect切面输出日志

这个不推荐,因为它无法打印出具体的url、header等数据,大家可以参考:

不需要yml配置,直接在项目里添加如下代码即可:

package com.example.demo.feign;import com.fasterxml.jackson.databind.ObjectMapper;import lombok.Data;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.stereotype.Component;@Aspect@Component@Slf4jpublic class FeignAspect {    // 这个也行 @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")    // 参考 https://github.com/spring-cloud/spring-cloud-openfeign/issues/322    @Pointcut("@within(org.springframework.cloud.openfeign.FeignClient)")    public void feignClientPointcut() {    }    @Around("feignClientPointcut()")    public Object feignAround(ProceedingJoinPoint joinPoint) throws Throwable {        return logAround(joinPoint);    }    private static ObjectMapper mapper = new ObjectMapper();    private Object logAround(ProceedingJoinPoint point) throws Throwable {        long beginTime = System.currentTimeMillis();        Object result = null;        Exception exception = null;        try {            result = point.proceed();        } catch (Exception exp) {            exception = exp;        }        long time = System.currentTimeMillis() - beginTime;        saveLog(point, result, exception, time);        if (exception != null) {            throw exception;        }        return result;    }    private static void saveLog(ProceedingJoinPoint joinPoint, Object result, Exception exception, long time) {        Dto dto = new Dto();        dto.setCostTime(time);        try {            if (exception != null) {                dto.setExp(exception.toString());            }            if (result != null) {                dto.setResult(serial(result));            }            MethodSignature signature = (MethodSignature) joinPoint.getSignature();            //请求的 类名、方法名            String className = joinPoint.getTarget().getClass().getName();            String signName = signature.getDeclaringTypeName();            if (!signName.equalsIgnoreCase(className))                signName += "|" + className;            dto.setClas(signName);            String methodName = signature.getName();            dto.setMethod(methodName);            //请求的参数            Object[] args = joinPoint.getArgs();            if (args != null && args.length > 0) {                dto.setPara(serial(args));            }        } catch (Exception e) {            dto.setExp(e.toString());        }        if (exception != null) {            log.warn(dto.toString());        } else {            log.info(dto.toString());        }    }    private static String serial(Object obj) {        try {            return mapper.writeValueAsString(obj);        } catch (Exception ex) {            return obj.toString();        }    }    @Data    private static class Dto {                private String clas;                private String method;                private String para;                private String result;                private long costTime;                private String remark;                private String exp;    }}

OK,输出的日志如下:

2020-10-13 14:24:48.321  INFO 21304 --- [nio-8080-exec-3] com.example.demo.feign.FeignAspect       : FeignAspect.Dto(clas=com.example.demo.feign.FeignDemo|com.sun.proxy.$Proxy72, method=test, para=null, result="<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true class="lazy" data-src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class=\"bg s_ipt_wr\"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class=\"bg s_btn_wr\"><input type=submit id=su value=百度一下 class=\"bg s_btn\" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=https://file.lsjlt.com/upload/202306/28/2lmqiwr140b.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href=\"https://file.lsjlt.com/upload/202306/28/2lmqiwr140b.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === \"\" ? \"?\" : \"&\")+ \"bdorz_come=1\")+ '\" name=\"tj_login\" class=\"lb\">登录</a>');\r\n                </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style=\"display: block;\">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img class="lazy" data-src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

关于“Feign的请求和响应日志方式是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Feign的请求和响应日志方式是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Feign的请求和响应日志方式是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Feign的请求和响应日志方式是什么

这篇文章主要介绍了Feign的请求和响应日志方式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Feign的请求和响应日志方式是什么文章都会有所收获,下面我们一起来看看吧。1、项目里定义FeignClien
2023-07-02

gateway、webflux、reactor-netty请求日志输出的方式是什么

本篇内容介绍了“gateway、webflux、reactor-netty请求日志输出的方式是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所
2023-06-29

HTTP请求报文和响应报文是什么

这篇文章主要介绍了HTTP请求报文和响应报文是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇HTTP请求报文和响应报文是什么文章都会有所收获,下面我们一起来看看吧。HTTP报文是面向文本的,报文中的每一个字
2023-06-27

Spring MVC能响应HTTP请求的原因是什么

Spring MVC能响应HTTP请求的原因是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。很多Java面试官喜欢问这个问题:一个Spring MVC的项目文件里,开发人员
2023-06-02

vue axios中的get请求方式是什么

这篇文章主要讲解了“vue axios中的get请求方式是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue axios中的get请求方式是什么”吧!vue axios中的get请求一
2023-07-02

Log4j关闭Spring和Hibernate日志打印方式是什么

这篇文章主要介绍“Log4j关闭Spring和Hibernate日志打印方式是什么”,在日常操作中,相信很多人在Log4j关闭Spring和Hibernate日志打印方式是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希
2023-06-22

HTTP的请求方式GET和POST有什么区别

这篇文章主要介绍“HTTP的请求方式GET和POST有什么区别”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“HTTP的请求方式GET和POST有什么区别”文章能帮助大家解决问题。HTTP的两种常用请
2023-06-27

vue3响应式原理和api编写的方法是什么

这篇文章主要讲解了“vue3响应式原理和api编写的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue3响应式原理和api编写的方法是什么”吧!前言vue3响应式原理加api编写
2023-06-22

浏览器请求流程和PHP对请求的处理方法是什么

这篇“浏览器请求流程和PHP对请求的处理方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“浏览器请求流程和PHP对请求
2023-07-05

vue3响应式实现readonly的方法是什么

readonly的实现it("happypath",()=>{console.warn=vi.fn();constoriginal={foo:1,};constobserved=readonly({foo:1,});expect(original).not.toBe(observed);expect(observed.foo).toBe(1);//set不起作用observed.foo=2;expect(observed.foo).toBe(1);//当被set的时候,
2023-05-21

HTML请求方法get和post的区别是什么

HTML 请求方法 GET 和 POST 是 HTTP 协议中常用的两种请求方法,它们的主要区别如下:1. 数据传输方式:GET 请求将数据以查询字符串的形式附加在 URL 后面,而 POST 请求将数据放在请求体中,不会显示在 URL 中
2023-10-11

vue处理响应式数据的方法是什么

这篇“vue处理响应式数据的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue处理响应式数据的方法是什么”文章吧
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录