目录介绍

  • 13.0.0.1 什么是注解?系统内置的标准注解有哪些?SuppressWarnings用过没?Android中提供了哪些与线程相关的注解?
  • 13.0.0.2 什么是apt?apt的难点和优势?什么是注解处理器?抽象处理器中四个方法有何作用?annotationProcessor和apt区别?
  • 13.0.0.3 注解是怎么分类的?自定义注解又是怎么分类的?运行期注解原理是什么?实际注解案例有哪些?
  • 13.0.0.4 在自定义注解中,Annotation里面的方法为何不能是private?Annotation里面的方法参数有哪些?
  • 13.0.0.5 @Inherited是什么意思?注解是不可以继承的,这是为什么?注解的继承这个概念该如何理解?
  • 13.0.0.6 什么是依赖注入?依赖注入案例举例说明,有哪些方式,具备什么优势?依赖查找和依赖注入有什么区别?
  • 13.0.0.7 路由框架为何需要依赖注入,不用的话行不行?路由用什么方式注入,这些注入方式各具何特点,为何选择注解注入?
  • 13.0.0.8 实际开发中使用到注解有哪些,使用注解替代枚举?如何通过注解限定传入的类型?为何说枚举损耗性能?

注解基础系列博客

  • 01.Annotation注解详细介绍

    1.Annotation库的简单介绍
    2.@Nullable和@NonNull
    3.资源类型注释
    4.类型定义注释
    5.线程注释
    6.RGB颜色纸注释
    7.值范围注释
    8.权限注释
    9.重写函数注释
    10.返回值注释
    11.@Keep注释
    12.@SuppressWarnings注解
    13.其他
    复制代码
  • 02.Dagger2深入分析,待更新
  • 03.注解详细介绍
    • 什么是注解,注解分类有哪些?自定义注解分类?运行注解案例展示分析,以一个最简单的案例理解注解……使用注解替代枚举,使用注解限定类型
  • 04.APT技术详解
    • 什么是apt?理解注解处理器的作用和用途……android-apt被替代?annotationProcessor和apt区别? 什么是jack编译方式?
  • 06.自定义annotation注解
    • @Retention的作用?@Target(ElementType.TYPE)的解释,@Inherited注解可以被继承吗?Annotation里面的方法为何不能是private?
  • 07.注解之兼容kotlin
    • 后期更新
  • 08.注解之处理器类Processor
    • 处理器类Processor介绍,重要方法,Element的作用,修饰方法的注解和ExecutableElement,了解修饰属性、类成员的注解和VariableElement……
  • 10.注解遇到问题和解决方案
    • 无法引入javax包下的类库,成功运行一次,修改代码后再运行就报错
  • 11.注解代替枚举
    • 在做内存优化时,推荐使用注解代替枚举,因为枚举占用的内存更高,如何说明枚举占用内存高呢?这是为什么呢?
  • 12.注解练习案例开源代码
    • 注解学习小案例,比较系统性学习注解并且应用实践。简单应用了运行期注解,通过注解实现了setContentView功能;简单应用了编译器注解,通过注解实现了防暴力点击的功能,同时支持设置时间间隔;使用注解替代枚举;使用注解一步步搭建简单路由案例。结合相应的博客,在来一些小案例,从此应该对注解有更加深入的理解……

好消息

  • 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计N篇[近100万字,陆续搬到网上],转载请注明出处,谢谢!
  • 链接地址:github.com/yangchong21…
  • 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议或者问题,万事起于忽微,量变引起质变!

13.0.0.1 什么是注解?系统内置的标准注解有哪些?SuppressWarnings用过没?Android中提供了哪些与线程相关的注解?

  • 什么是注解?

    • Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息或者任何元数据(metadata)的途径和方法。基本规则:Annotation(注解)不能影响程序代码的执行,无论增加,删除Annotation(注解),代码都始终如一的执行。
  • 系统内置的标准注解有哪些?
    • @Override表示子类对父类方法的重写所带的注解;@Deprecated表示已经过时,不建议使用,但是依然可以使用;@SuppressWarnings("all")用来抑制编译时的警告信息,编译器在你写代码的时候,难免会出现很多的警告,有强迫症的程序猿会感到极其不爽,那么肿么办呢?@SuppressWarnings注解就可以告诉编译器,别警告啦,代码不会有问题的。
  • SuppressWarnings用过没?
    • @SuppressWarnings注解一定要传递一个参数给它,来表示过滤掉哪些类型的警告,笔者添加了”all”表示过滤掉所有类型的警告,很好理解吧!那么还可以传递什么参数来过滤警告呢?看看下面的表格你就会知道啦:
  • Android中提供了哪些与线程相关的注解?
    • @UiThread,通常可以等同于主线程,标注方法需要在UIThread执行,比如View类就使用这个注解
    • @MainThread 主线程,经常启动后创建的第一个线程
    • @WorkerThread 工作者线程,一般为一些后台的线程,比如AsyncTask里面的doInBackground就是这样的
    • @BinderThread 注解方法必须要在BinderThread线程中执行,一般使用较少

13.0.0.2 什么是apt?apt的难点和优势?什么是注解处理器?抽象处理器中四个方法有何作用?annotationProcessor和apt区别?

  • 什么是apt?

    • APT(Annotation Processing Tool的简称),可以在代码编译期解析注解,并且生成新的Java文件,减少手动的代码输入。现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife等
  • apt的难点和优势?
    • 难点:就apt本身来说没有任何难点可言,难点一在于设计模式和解耦思想的灵活应用,二在与代码生成的繁琐,你可以手动字符串拼接,当然有更高级的玩法用squareup的javapoet,用建造者的模式构建出任何你想要的源代码
    • 优点:它的强大之处无需多言,看代表框架的源码,你可以学到很多新姿势。总的一句话:它可以做任何你不想做的繁杂的工作,它可以帮你写任何你不想重复代码。
  • 什么是注解处理器?
    • 注解处理器是一个在javac中的,用来编译时扫描和处理的注解的工具。你可以为特定的注解,注册你自己的注解处理器。
    • 注解处理器可以生成Java代码,这些生成的Java代码会组成 .java 文件,但不能修改已经存在的Java类(即不能向已有的类中添加方法)。而这些生成的Java文件,会同时与其他普通的手写Java源代码一起被javac编译。
  • 抽象处理器中四个方法有何作用?
    • 每一个注解处理器都要继承于AbstractProcessor,如下所示:

      public class MyProcessor extends AbstractProcessor{@Overridepublic synchronized void init(ProcessingEnvironment processingEnvironment){super.init(processingEnvironment);}@Overridepublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment){return false;}@Overridepublic Set<String> getSupportedAnnotationTypes(){return super.getSupportedAnnotationTypes();}@Overridepublic SourceVersion getSupportedSourceVersion(){return super.getSupportedSourceVersion();}
      }
      复制代码
    • 这几个方法如下
      • init(ProcessingEnvironment processingEnvironment): 每一个注解处理器类都必须有一个空的构造函数。然而,这里有一个特殊的init()方法,它会被注解处理工具调用,并输入ProcessingEnviroment参数。ProcessingEnviroment提供很多有用的工具类Elements,Types和Filer。后面我们将看到详细的内容。
      • process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment): 这相当于每个处理器的主函数main()。你在这里写你的扫描、评估和处理注解的代码,以及生成Java文件。输入参数RoundEnviroment,可以让你查询出包含特定注解的被注解元素。后面我们将看到详细的内容。
      • getSupportedAnnotationTypes(): 这里你必须指定,这个注解处理器是注册给哪个注解的。注意,它的返回值是一个字符串的集合,包含本处理器想要处理的注解类型的合法全称。换句话说,你在这里定义你的注解处理器注册到哪些注解上。
      • getSupportedSourceVersion(): 用来指定你使用的Java版本。通常这里返回SourceVersion.latestSupported()。然而,如果你有足够的理由只支持Java 7的话,你也可以返回SourceVersion.RELEASE_7。我推荐你使用前者。
  • annotationProcessor和apt区别?
    • Android 官方的 annotationProcessor 同时支持 javac 和 jack 编译方式,而 android-apt 只支持 javac 方式。当然,目前 android-apt 在 Android Gradle 插件 2.2 版本上面仍然可以正常运行,如果你没有想支持 jack 编译方式的话,可以继续使用 android-apt。
  • 什么是jack编译方式?
    • Jack (Java Android Compiler Kit)是新的Android 编译工具,从Android 6.0 开始加入,替换原有的编译工具,例如javac, ProGuard, jarjar和 dx。它主要负责将java代码编译成dex包,并支持代码压缩,混淆等。
  • Jack工具的主要优势
    • 完全开放源码,源码均在AOSP中,合作伙伴可贡献源码
    • 加快编译源码,Jack 提供特殊的配置,减少编译时间:pre-dexing, 增量编译和Jack编译服务器.
    • 支持代码压缩,混淆,重打包和multidex,不在使用额外单独的包,例如ProGuard。

13.0.0.3 注解是怎么分类的?自定义注解又是怎么分类的?运行期注解原理是什么?

  • 注解是怎么分类的?

    • 标准 Annotation

      • 包括 Override, Deprecated, SuppressWarnings,是java自带的几个注解,他们由编译器来识别,不会进行编译, 不影响代码运行,至于他们的含义不是这篇博客的重点,这里不再讲述。
    • 元 Annotation
      • @Retention, @Target, @Inherited, @Documented,它们是用来定义 Annotation 的 Annotation。也就是当我们要自定义注解时,需要使用它们。
    • 自定义 Annotation
      • 根据需要,自定义的Annotation。而自定义的方式,下面我们会讲到。
  • 自定义注解又是怎么分类的?
    • 同样,自定义的注解也分为三类,通过元Annotation - @Retention 定义:
    • @Retention(RetentionPolicy.SOURCE)
      • 源码时注解,一般用来作为编译器标记。如Override, Deprecated, SuppressWarnings。
    • @Retention(RetentionPolicy.RUNTIME)
      • 运行时注解,在运行时通过反射去识别的注解。
      • 定义运行时注解,只需要在声明注解时指定@Retention(RetentionPolicy.RUNTIME)即可。
      • 运行时注解一般和反射机制配合使用,相比编译时注解性能比较低,但灵活性好,实现起来比较简答。
    • @Retention(RetentionPolicy.CLASS)
      • 编译时注解,在编译时被识别并处理的注解,这是本章重点。
      • 编译时注解能够自动处理Java源文件并生成更多的源码、配置文件、脚本或其他可能想要生成的东西。
  • 运行期注解原理是什么?
  • 实际注解案例有哪些?
    • 运行时注解:retrofit
    • 编译时注解:Dagger2, ButterKnife, EventBus3

13.0.0.4 在自定义注解中,Annotation里面的方法为何不能是private?Annotation里面的方法参数有哪些?

  • Annotation里面的方法为何不能是private?

    • 只能用public或默认(default)这两个访问权修饰.例如,String value();不能是private;因为它是提供给外部使用的。
  • Annotation里面的方法参数有哪些
    • 参数只能使用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数类型就为String; 

13.0.0.5 @Inherited是什么意思?注解是不可以继承的,这是为什么?注解的继承这个概念该如何理解?

  • @Inherited是什么意思?

    • 该注解的字面意识是继承,但你要知道注解是不可以继承的。@Inherited是在继承结构中使用的注解。
    • 如果你的注解是这样定义的:
      • 当你的注解定义到类A上,此时,有个B类继承A,且没使用该注解。但是扫描的时候,会把A类设置的注解,扫描到B类上。
      @Inherited
      @Retention(RetentionPolicy.CLASS)
      @Target(ElementType.TYPE)
      public @interface Test {//...
      }
      复制代码
  • 注解是不可以继承的,这是为什么?
    • 注解不能继承
  • 注解的继承这个概念该如何理解?
    • 这里讲的继承并不是通过@Inherited修饰的注解。这个“继承”是一个注解的使用技巧,使用上的感觉类似于依赖倒置,来自于ButterKnife源码。
    • 这是ButterKnife的OnClick 注解。特殊的地方在于**@OnClick修饰了注解@ListenerClass**,并且设置了一些只属于@OnClick的属性。
    • 那这样的作用是什么呢?凡是修饰了@OnClick的地方,也就自动修饰了@ListenerClass。类似于@OnClick是@ListenerClass的子类。而ButterKnife有很多的监听注解@OnItemClick、@OnLongClick等等。这样在做代码生成时,不需要再单独考虑每一个监听注解,只需要处理@ListenerClass就OK。
    @Target(METHOD)
    @Retention(CLASS)
    @ListenerClass(targetType = "android.view.View",setter = "setOnClickListener",type = "butterknife.internal.DebouncingOnClickListener",method = @ListenerMethod(name = "doClick",parameters = "android.view.View")
    )
    public @interface OnClick {/** View IDs to which the method will be bound. */int[] value() default { View.NO_ID };
    }
    复制代码

13.0.0.6 什么是依赖注入?依赖注入案例举例说明,有哪些方式,具备什么优势?依赖查找和依赖注入有什么区别?

  • 什么是依赖注入

    • 在面向对象编程中,经常处理处理的问题就是解耦,程序的耦合性越低表明这个程序的可读性以及可维护性越高。控制反转(Inversion of Control或IoC)就是常用的面向对象编程的设计原则,使用这个原则我们可以降低耦合性。其中依赖注入是控制反转最常用的实现。
  • 依赖注入案例举例说明,有哪些方式,具备什么优势?
    • 依赖是程序中常见的现象,比如类Car中用到了GasEnergy类的实例energy,通常的做法就是在Car类中显式地创建GasEnergy类的实例,并赋值给energy。如下面的代码

      interface Energy {}class GasEnergy implements Energy {}class Car {Energy energy = new GasEnergy();
      }
      复制代码
    • 存在问题
      • 类Car承担了多余的责任,负责energy对象的创建,这必然存在了严重的耦合性。举一个现实中的例子,一辆汽车使用哪种能源不是由汽车来决定,而是由汽车制造商(CarMaker)来决定,这是汽车制造商的责任。
      • 可扩展性,假设我们想修改能源为电动力,那么我们必然要修改Car这个类,明显不符合开放闭合原则。
      • 不利于单元测试。
    • 有哪些方式解耦
      • 依赖注入是这样的一种行为,在类Car中不主动创建GasEnergy的对象,而是通过外部传入GasEnergy对象形式来设置依赖。 常用的依赖注入有如下三种方式
    • 构造器注入
      • 将需要的依赖作为构造方法的参数传递完成依赖注入。
      class Car {Energy mEnergy;public Car(Energy energy) {mEnergy = energy;}
      }
      复制代码
    • Setter方法注入
      • 增加setter方法,参数为需要注入的依赖亦可完成依赖注入。
      class Car {Energy mEnergy;public void setEnergy(Energy energy) {mEnergy  = energy;}
      }
      复制代码
    • 接口注入
      • 接口注入,闻其名不言而喻,就是为依赖注入创建一套接口,依赖作为参数传入,通过调用统一的接口完成对具体实现的依赖注入。
      • 接口注入和setter方法注入类似,不同的是接口注入使用了统一的方法来完成注入,而setter方法注入的方法名称相对比较随意。
      interface EnergyConsumerInterface {public void setEnergy(Energy energy);
      }class Car implements EnergyConsumerInterface {Energy mEnergy;public void setEnergy(Energy energy) {mEnergy  = energy;}
      }
      复制代码
  • 依赖查找和依赖注入
    • 依赖查找和依赖注入一样属于控制反转原则的具体实现,不同于依赖注入的被动接受,依赖查找这是主动请求,在需要的时候通过调用框架提供的方法来获取对象,获取时需要提供相关的配置文件路径、key等信息来确定获取对象的状态。

13.0.0.7 路由框架为何需要依赖注入,不用的话行不行?路由用什么方式注入,这些注入方式各具何特点,为何选择注解注入?

  • 路由框架为何需要依赖注入,不用的话行不行?

    • 路由的目的就是要实现跳转,但是你有没有想过,两个Activity之间的跳转肯定免不了要传入一些参数,如果我们在跳转后还要通过intent去获取参数,这样岂不是很麻烦,如果可以自动把参数赋给属性多好啊!
    • 组件化中两个module之间可能有一些功能并不需要跳转页面,如支付模块要获取用户模块的用户id,并不需要跳转页面,那么我们就要持有用户模块含有获取用户id功能的类的引用,如果我们在支付模块创建一个用户模块的功能引用,显然就违背了解耦的规则。这两个问题显然用依赖注入的方式会更好些,如果你用过ARouter,你会发现ARouter中的服务(IProvider)就是通过依赖注入实现的。
  • 路由用什么方式注入,这些注入方式各具何特点,为何选择注解注入?
    • 可以使用注解的方式,至于为啥,接下来我分析一下……

      • 为什么要用注解实现依赖注入,因为我们用了apt啊,那岂不是天生实现依赖注入的利器。如果你去写配置文件或构造方法等等,未免太复杂。
    • 无法通过构造方法注入【构造器注入】
      • 在多组件并行开发过程中,因为两个module没有引用关系,所以就不能通过构造方法传入要依赖的类,这个时候怎么办呢?连对方的引用都得不到,如何进行依赖呢?
    • 不要通过反射方式注入
      • 可能你会想到反射,我们先pass这个方案,能不用反射就能做好的前提下,我们最好不要用反射。
    • 不建议通过接口方式注入【也可以,但若是开源成lib,则不建议】
      • 可能有人会想到,在基类下沉一个接口功能标准,比如在基类库base模块定义获取用户id的接口,然后在用户模块实现接口的方法。那么当支付模块需要用到这个功能,就声明这个接口,然后一行注解通过框架为你创建实例,这样用户模块只需要提供功能,并不需要关心谁在用这个功能,这样岂不是大大减小了耦合。
      • 但是有一点,组件化实践中,有很多个模块,那岂不是所有的都需要依赖base基类库,才能使用到接口注入,这样不易转接。

13.0.0.8 实际开发中使用到注解有哪些,使用注解替代枚举?如何通过注解限定传入的类型?为何说枚举损耗性能?

  • 实际开发中使用到注解有哪些,使用注解替代枚举?

    • 代码如下所示
    • 具体的案例,可以看我视频播放器开源库:github.com/yangchong21…
    /*** 播放模式* -1               播放错误* 0                播放未开始* 1                播放准备中* 2                播放准备就绪* 3                正在播放* 4                暂停播放* 5                正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)* 6                正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,此时暂停播放器,继续缓冲,缓冲区数据足够后恢复暂停* 7                播放完成*/
    public @interface CurrentState{int STATE_ERROR = -1;int STATE_IDLE = 0;int STATE_PREPARING = 1;int STATE_PREPARED = 2;int STATE_PLAYING = 3;int STATE_PAUSED = 4;int STATE_BUFFERING_PLAYING = 5;int STATE_BUFFERING_PAUSED = 6;int STATE_COMPLETED = 7;
    }
    复制代码
  • 如何通过注解限定传入的类型?
    • 代码如下所示
    • 具体的案例,可以看我视频播放器开源库:github.com/yangchong21…
    • 枚举最大的作用是提供了类型安全。为了弥补Android平台不建议使用枚举的缺陷,官方推出了两个注解,IntDef和StringDef,用来提供编译期的类型检查。
    • 倘若,传入的值不是IjkPlayerType中的类型,则会导致编译提醒和警告。
     /*** 通过注解限定类型* TYPE_IJK                 IjkPlayer,基于IjkPlayer封装播放器* TYPE_NATIVE              MediaPlayer,基于原生自带的播放器控件*/
    @Retention(RetentionPolicy.SOURCE)
    public @interface IjkPlayerType {int TYPE_IJK = 111;int TYPE_NATIVE = 222;
    }
    @IntDef({IjkPlayerType.TYPE_IJK,IjkPlayerType.TYPE_NATIVE})
    public @interface PlayerType{}//使用
    /*** 设置播放器类型,必须设置* 注意:感谢某人建议,这里限定了传入值类型* 输入值:ConstantKeys.IjkPlayerType.TYPE_IJK   或者  ConstantKeys.IjkPlayerType.TYPE_NATIVE* @param playerType IjkPlayer or MediaPlayer.*/
    public void setPlayerType(@ConstantKeys.PlayerType int playerType) {mPlayerType = playerType;
    }
    复制代码

关于其他内容介绍

01.关于博客汇总链接

  • 1.技术博客汇总
  • 2.开源项目汇总
  • 3.生活博客汇总
  • 4.喜马拉雅音频汇总
  • 5.其他汇总

02.关于我的博客

  • 我的个人站点:www.yczbj.org,www.ycbjie.cn
  • github:github.com/yangchong21…
  • 知乎:www.zhihu.com/people/yczb…
  • 简书:www.jianshu.com/u/b7b2c6ed9…
  • csdn:my.csdn.net/m0_37700275
  • 喜马拉雅听书:www.ximalaya.com/zhubo/71989…
  • 开源中国:my.oschina.net/zbj1618/blo…
  • 泡在网上的日子:www.jcodecraeer.com/member/cont…
  • 邮箱:yangchong211@163.com
  • 阿里云博客:yq.aliyun.com/users/artic… 239.headeruserinfo.3.dT4bcV
  • segmentfault头条:segmentfault.com/u/xiangjian…
  • 掘金:juejin.im/user/593943…

03.12.注解练习案例开源代码

13.Android之注解问题相关推荐

  1. android注解的作用,Android 用注解来提升代码质量

    Android 用注解来提升代码质量 Android,注解,annotation 2018.07.13 Android 提供了一个注解的 support 包,这个注解包配合 IDE 可以用来提升我的代 ...

  2. 细说 Android Annotations 注解框架

    本文首发知识星球<Hi Android> 注解不是必须的,但是能极大的帮助我们节约时间和提高开发效率,写此篇文章的初衷,是我课程中的同学想要了解一下这个框架,遂写下此篇文章,其实我们如果想 ...

  3. 《Android App开发入门:使用Android Studio 2.X开发环境》——1-3 Android Studio 快速上手...

    1-3 Android Studio 快速上手

  4. Android Annotation注解详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/119874435 本文出自[赵彦军的博客] 文章目录 Java注解 元注解说明 @R ...

  5. android 使用注解

    使用注解改进代码检查 本文内容 向您的项目添加注解 添加支持注解库依赖项 运行代码检查 Nullness 注解 Nullability 分析 资源注解 线程注解 值约束注解 权限注解 间接权限 返回值 ...

  6. 【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置

    [SA8295P 源码分析]13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置 一.QUP v3 介绍 二.QUP v3 UART 功能配置 2. ...

  7. Android 自定义注解(Annotation)

    现在市面上很多框架都有使用到注解,比如butterknife库.EventBus库.Retrofit库等等.也是一直好奇他们都是怎么做到的,注解的工作原理是啥.咱们能不能自己去实现一个简单的注解呢.注 ...

  8. Android 基于注解IOC组件化/模块化的架构实践

    当前参与的项目历史也很久远,第一行代码据说是写于2014年的某一天,那时Android用的ide还是Eclipse.那时Android还没有很好的架构指导(mvp.mvvm).那时Android最新的 ...

  9. android使用 注解框架,Android实践 | 注解框架ButterKnife基本使用

    使用ButterKnife,我们可以不用写很多的findViewById()语句,以及通过getResources获取String.Color等资源,这可以让我们的代码更加简洁,使用起来也很方便.下面 ...

最新文章

  1. xgboost 的 get_fscore()
  2. Quartz调度器学习--基本概念
  3. 常用的Linux命令合集,建议收藏保存!
  4. (一)ubuntu下qtcreator +opencv下新建一个项目和调用caffe环境配置
  5. 云计算学习(1-1)云计算的定义
  6. Bitmovin:视频开发者报告2018
  7. C语言高级编程:数组和指针作为函数形参
  8. 微软:Vista SP2是最安全的操作系统
  9. [react] React Intl是什么原理?
  10. python 加权随机算法_python中的加权随机样本
  11. java代码实际_Java 8会给你的代码带来什么:一个实际的例子
  12. redis用zset做延时消息
  13. 【渝粤教育】广东开放大学 经济学基础 形成性考核 (25)
  14. VM虚拟机下CentOS 6.5配置IP地址的三种方法
  15. (专升本)Excel(分页符的删除)
  16. 【iOS】 Foundation 数组
  17. 微软认知服务应用秘籍 – 支持跨平台客户端的视觉服务中间层
  18. java redis 实现pv uv_redis实战-记录PV与UV
  19. 2022年全球与中国湿钽电容器行业发展趋势及投资战略分析报告
  20. Google MicroData,谷歌微数据为博客添加评级

热门文章

  1. 计算机控制的电冰箱,详解电脑控制型电冰箱维修基础
  2. 快速理解j=j++ 和 j=++j(新手入门)
  3. Web功能设计:验证码
  4. 16S的细菌群落功能预测工具PICRUSt2学习
  5. 海思芯片怎么使用tde给qt加速_海思芯片图形层的开发指南与方案
  6. jupyter notebook中使用R语言
  7. android数据回传多个页面_Android菜鸟起飞|使用Intent实现Activity跳转的两种方式(无回传数据和有回传数据)...
  8. EDIUS压片模糊问题该怎样解决
  9. DDPush开源推送框架源码分析之APPServer到DDPush
  10. 8月28日服务器例行维护公告,2008年8月28日维护公告