一. Application 分析

1. Application 简介

(1) Application 概念

Application 概念 : Application 属于组件范畴;

-- 本质 : Application 与 四大组件 一样也属于 Android 中的组件;

-- 作用 : 用于存储系统 和 用户定义的全局信息;

-- Application 创建 : 应用开始运行时创建 Application 对象, 可以自定义, 也可以让系统自动创建;

-- Application 单例性 : 每个应用只创建一个 Application 对象, 该类属于单例模式;

-- Application 生命周期 : Application 生命周期 从应用启动开始 到 应用退出结束, 与应用的生命周期是相同的;

-- Application 作用 : 在任何组件中调用 getApplication() 或者通过 Context 对象调用 getApplicationContext() 方法获取的 Application 对象都是相同的, 因此可以使用 Application 进行数据共享, 数据缓存操作;

(2) Application 与 全局变量

Application 与 全局变量 :

-- 基本作用 : Application 在 Android 中是为了 保存全局变量 而设计的类;

-- Android 全局变量定义 : 在 Android 中可以不使用 public static 定义全局变量, 定义在 Application 中的普通变量 在Android应用中可以当作全局变量使用;

(3) Application 使用方法

Application 使用方法 :

-- 自定义 Application : 自定义一个 class 类, 继承 android.app.Application 类;

-- 配置 Application : 在 AndroidManifest.xml 中配置 Application;

-- 获取 Application : 在组件类(Activity, Service 等)中直接调用 getApplication() 方法即可, 在普通类中调用 Context 的 getApplicationContext() 方法;

2. Application 生命周期 及 对应方法

(1) onCreate()

onCreate() 方法简介 : 该方法是 Android 程序的入口;

-- 执行时机 : 该方法在应用创建时自动回调;

-- 注意 : 在父类 Application 中, onCreate() 方法方法体是空的, 这里可以不用执行 super.onCreate()方法;

关于程序入口 :

-- Android 程序入口 : Android 程序入口是 Application, 并不是 Activity, 因为有的 应用是没有 Activity 的;

-- Java 和 C 程序入口 : 这两种语言的程序入口是工程中的 main() 函数;

(2) onLowMemory()

onLowMemory() 方法简介 :

-- 调用时机 : 在内存不足时会回调该方法;

-- 重写方法 : 重写时需要执行父类方法 super.onLowMemory(), 同时根据本应用特点, 释放掉一些不必要的数据;

(3) onTerminate()

onTerminate() 方法简介 :

-- 调用时机 : 只有在模拟器中终止程序时才会回调该方法, 在 Android 真机中是不会回调该方法的;

-- 注意 : Application 的 onTerminate() 方法体是空的, 这里不许要执行父类的方法 super.onTerminate();

(4) onConfigurationChanged()

onConfigurationChanged() 方法简介 :

-- 调用时机 : 配置改变时回调这个方法;

(5) Application 代码分析

Application 相关代码 :

  1. /**
  2. * Called when the application is starting, before any other application
  3. * objects have been created.  Implementations should be as quick as
  4. * possible (for example using lazy initialization of state) since the time
  5. * spent in this function directly impacts the performance of starting the
  6. * first activity, service, or receiver in a process.
  7. * If you override this method, be sure to call super.onCreate().
  8. */
  9. public void onCreate() {
  10. }
  11. /**
  12. * This method is for use in emulated process environments.  It will
  13. * never be called on a production Android device, where processes are
  14. * removed by simply killing them; no user code (including this callback)
  15. * is executed when doing so.
  16. */
  17. public void onTerminate() {
  18. }
  19. public void onConfigurationChanged(Configuration newConfig) {
  20. Object[] callbacks = collectComponentCallbacks();
  21. if (callbacks != null) {
  22. for (int i=0; i<callbacks.length; i++) {
  23. ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
  24. }
  25. }
  26. }
  27. public void onLowMemory() {
  28. Object[] callbacks = collectComponentCallbacks();
  29. if (callbacks != null) {
  30. for (int i=0; i<callbacks.length; i++) {
  31. ((ComponentCallbacks)callbacks[i]).onLowMemory();
  32. }
  33. }
  34. }

3. Application 使用场景 1 --> 组件间的数据传递

(1) 使用 Application 传递数据

Application 媒介传递数据方式 :

-- Appliction 集合 : 在 Application 中维护一个集合, 创建一个 HashMap 成员变量, 键是字符串, 值是 Object 对象, 这样 这个 HashMap 可以存储任何类型的对象;

-- 共享过程 : Activity A 将数据存储到 HashMap 中, 将 键 通过 Intent 的 Bundle 传递给 Activity B, 之后在 Activity B 中取出对象, 并将 HashMap 中的对象删除;

-- 适用范围 : 如果跳转的两个 Activity 在同一个 应用 中, 可以使用这种方法;

(2) 传统传递数据方式

传统数据传递 : Activity A 跳转到 Activity B;

-- 实体类 Bean 处理 : bean 实体类必须实现 Serializable或者Parcellable接口, 才可以将实体类 bean 对象放入 Intent 的 Bundle 中;

-- 数据传递过程 : 在 Activity A 中将 实现了 Serializable 或者 Parcellable 接口的实体类对象放入 Intent 的 Bundle 中, 跳转到 Activity B;

4. Application 使用场景 2 --> 应用中的数据缓存

Application 缓存数据 :

-- 缓存少量数据 : 从互联网获取的少量数据可以直接存放在 Application 中用于数据缓存的 HashMap 中;

-- 缓存大量数据 : 如果缓存 数据 或者 文件, 可以将文件缓存到本地, 然后在 Application 中缓存一个 文件路径字符串即可;

-- 释放缓存 : 在 onLowMemory() 方法中可以释放这些缓存, 因为这些缓存可有可无, 这里为了性能牺牲访问速度;

数据传递, 缓存 Application 示例 :

  1. package cn.org.octopus.application;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import android.app.Application;
  5. public class MyApplication extends Application {
  6. /** 用于数据传递的 Map 集合 */
  7. private Map<String, Object> transferMap;
  8. /** 用于缓存数据的 Map 集合 */
  9. private Map<String, Object> cacheMap;
  10. @Override
  11. public void onCreate() {
  12. super.onCreate();
  13. //初始化用于数据传递的 Map 集合
  14. transferMap = new HashMap<String, Object>();
  15. //初始化用于数据缓存的 Map 集合
  16. cacheMap = new HashMap<String, Object>();
  17. }
  18. /**
  19. * 获取数据传递 Map 集合
  20. * @return
  21. *      数据传递 Map 集合
  22. */
  23. public Map<String, Object> getTransferMap() {
  24. return transferMap;
  25. }
  26. /**
  27. * 获取数据缓存 Map 集合
  28. * @return
  29. *      数据缓存 Map 集合
  30. */
  31. public Map<String, Object> getCacheMap() {
  32. return cacheMap;
  33. }
  34. }

5. Application 与 内存泄漏

(1) Application 内存泄漏

Application 内存分析 :

-- 注意存放对象 : Application 中如果保存了一些大的对象, 例如 Activity 等组件, 如果没有释放, 将会引起很多内存泄漏;

-- 内存释放 : 在 Application 中要经常注意释放不许要的对象, 使用完毕后能释放掉的就释放, 在 onLowMemory() 方法中将所有的缓存数据都清空;

(2) Application 尽量不要持有 组件引用

组件持有 Context 对象 :

-- 创建组件 : TextView tv = new TextView(Activity activity), 这样一来 组件持有了 Activity 或者 Context 对象;

-- 组件持久化 : 当将持有 Context的 tv 组件设置为静态 或者 将 tv 组件设置到 Application 中时, tv 的声明周期就变成了整个应用的声明周期了;

-- Context 无法释放 : 此时 当 Activity 退出后, 组件仍然存在, Conetxt 无法释放, 一旦多次访问这个 Activity, 每次都会泄漏 Context 大小的内存;

防止内存泄漏方法 :

-- 组件 : Activity 中的组件的声明周期不要超出 Activity 生命周期;

-- 图片 : 组件使用的 Drawable 对象不要超出 Actiity 声明周期;

-- 线程持有对象 : 不要在线程中持有 Context, 否则在线程执行完毕之前都处于内存泄漏状态;

-- 内部类作用域不要超出 Activity : 如果在 Activity A 中定义了内部类, 不要将这个内部类传递给其它 Activity 等组件, 否则该 Activity A 不能释放, 建议将内部类设置成 static 或者 单独写成一个类;

二. Application 应用层源码分析

1. Application 类结构分析

(1)  Application 继承关系

Application 类继承结构 :

-- Application 类 : public class Application extends ContextWrapper implements ComponentCallbacks2 ;

-- ContextWrapper 类 : public class ContextWrapper extends Context ;

-- Context 类 : public abstract class Context;

-- ComponentCallbacks2 接口 : public interface ComponentCallbacks2 extends ComponentCallbacks ;

-- ComponentCallbacks 接口 : public interface ComponentCallbacks ;

-- UML 图 :

(2) 相关类介绍

Application 相关类介绍 :

-- Application 类 : 用于存储应用的全局变量;

-- ContextWrapper 类 : 该类是 Context 简单的代理实现, 代表了对另一个 Context 的调用, 在该类的子类中可以重写对应方法改变指定的操作行为;

-- Context 类 : 该 抽象类 是 应用环境的全局信息接口, Android 提供了该抽象类的实现类, 该类用于访问 应用的 资源 和 类 (作用一)返回 应用的 Actiity, 广播, Intent 等操作的执行结果(作用二);

-- ComponentCallbacks2 接口 : 该接口继承了 ComponentCallbacks, 用于 更细粒度的内存管理;

-- ComponentCallbacks 接口 : 应用组件的回调接口, 所有的组件都要实现这个接口;

2. CompnentCallbacks 接口

部分源码 : 省略了注释部分, 代码完整;

  1. package android.content;
  2. import android.content.res.Configuration;
  3. public interface ComponentCallbacks {
  4. void onConfigurationChanged(Configuration newConfig);
  5. void onLowMemory();
  6. }

(1) onConfigurationChanged() 方法介绍

方法介绍 : 该方法回调后需要重新加载新配置对应的资源, 如果 Activity 对应配置改变需要 重启组件, 其它组件不用重启;

-- 方法全称 : void onConfigurationChanged(Configuration newConfig);

-- 回调时机 : 在组件运行时, 如果发生了设备的配置改变, 就会回调该接口的方法;

-- 重新加载资源 : 当配置改变, 该方法回调后, 需要更新资源, 以找到与新配置匹配的资源, 例如屏幕方向改变了, 需要找 drawable-land (横屏) 或者 drawable-port (竖屏资源);

-- Activity 组件配置改变 : 当 Activity 运行的时候, 如果配置发生改变, 需要进行重新启动, 例如 横屏 切换 竖屏;

-- 其它组件配置改变 : 在 Service 等组件运行时, 配置发生改变, 不需要重新启动;

(2) onLowMemory() 方法介绍

方法介绍 :

-- 方法全称 : void onLowMemory();

-- 回调时机 : 当系统剩余内存比较低的时候, 并且系统想要 清理内存以获取更多内存时 回调该方法;

-- 时间点不确定 : 不能确定方法回调准确的时间点, 大概在所有的后台进行被杀死的时间点 左右 回调该方法, 这个时间点在 服务进程被杀死之前;

-- 避免杀死前台进程 : UI 进程在清理内存时, 是应该避免被杀死的, 这类进程尽量保存;

-- 方法中的建议操作 : 组件实现该方法, 在该方法中建议进行 释放缓存 或者 释放不需要持有的资源, 执行该方法后, 系统会执行 GC 垃圾回收;

3. ComponentCallbacks2 接口

源码示例 : 一部份源码, 省略了注释 和 一部份的 常量;

  1. package android.content;
  2. public interface ComponentCallbacks2 extends ComponentCallbacks {
  3. static final int TRIM_MEMORY_COMPLETE = 80;
  4. static final int TRIM_MEMORY_MODERATE = 60;
  5. ... ...
  6. void onTrimMemory(int level);
  7. }

(1) onTrimMemory() 方法介绍

方法介绍 :

-- 方法全称 : void onTrimMemory(int level) ;

-- 回调时机 : 当 系统决定要清理一个进程不必要的内存时 回调该方法;

-- 清理内存时机 : 后台进程运行时, 当没有足够的内存去保持这些后台进程运行时, 就会进行内存清理;

-- 内存等级 : 每个等级都有一个对应的内存值, 但是这个内存等级的精确值是无法获取的, 因为随时都有新的中间值会累加上去;

(2) 内存等级常量介绍

LRU list 概念 : 全称 Least Recently Used, 即最近最少使用算法, 用于内存管理;

常量 TRIM_MEMORY_COMPLETE :

-- 全称 : static final int TRIM_MEMORY_COMPLETE = 80;

-- 作用 : 表示 后台进程中的 LRU (最近最少使用) 队列的尾部, 如果需要更多内存, 这些进程将被杀死;

常量 TRIM_MEMORY_MODERATE :

-- 全称 : static final int TRIM_MEMORY_MODERATE = 60 ;

-- 作用 : 表示 LRU 进程队列的 中间部分, 释放队列中间及后面进程的内存, 会提高手机性能;

常量用法 : 其中定义了很多类似的常量, 代表一部份进程, 将该常量传入 onTrimMemory(int level) 可以杀死指定集合的进程;

4. Application 类分析

(1) ComponentCallbacks 集合列表

列表定义 :

-- 定义方式 : private ArrayList<ComponentCallbacks> mComponentCallbacks = new ArrayList<ComponentCallbacks>();

-- 使用位置 : 在 onConfigurationChanged(), onLowMemory(), onTrimMemory() 方法中使用了 该列表;

-- 执行内容 : ComponentCallbacks 子类 即组件, 都实现了上面的三种方法, 在 Application 中的对应方法中分别遍历组件调用组件本身的对应方法;

注册 和 删除组件 : 每创建一个组件都将这个组件注册, 组件销毁时 从列表中删除组件;

  1. public void registerComponentCallbacks(ComponentCallbacks callback) {
  2. synchronized (mComponentCallbacks) {
  3. mComponentCallbacks.add(callback);
  4. }
  5. }
  6. public void unregisterComponentCallbacks(ComponentCallbacks callback) {
  7. synchronized (mComponentCallbacks) {
  8. mComponentCallbacks.remove(callback);
  9. }
  10. }

(2) ActivityLifecycleCallbacks 接口介绍

ActivityLifecycleCallbacks 接口介绍 :

-- 接口作用 : 该接口提供了一套监测 Activity 声明周期的回调方法;

-- 注册 Activity 声明周期监听方法 :

  1. public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
  2. synchronized (mActivityLifecycleCallbacks) {
  3. mActivityLifecycleCallbacks.add(callback);
  4. }
  5. }

-- 取消监听方法 :

  1. public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
  2. synchronized (mActivityLifecycleCallbacks) {
  3. mActivityLifecycleCallbacks.remove(callback);
  4. }
  5. }

-- 接口代码 :

  1. public interface ActivityLifecycleCallbacks {
  2. void onActivityCreated(Activity activity, Bundle savedInstanceState);
  3. void onActivityStarted(Activity activity);
  4. void onActivityResumed(Activity activity);
  5. void onActivityPaused(Activity activity);
  6. void onActivityStopped(Activity activity);
  7. void onActivitySaveInstanceState(Activity activity, Bundle outState);
  8. void onActivityDestroyed(Activity activity);
  9. }

三. Application 相关示例

1. 自定义 Application 基本使用

(1) 创建 自定义 Application

创建 Application : 创建一个类, 继承 android.app.Application 类, 实现最基本的 onCreate() 方法即可;

-- 示例 :

  1. package cn.org.octopus.application;
  2. import android.app.Application;
  3. public class MyApplication extends Application {
  4. @Override
  5. public void onCreate() {
  6. super.onCreate();
  7. }
  8. }

(2) 注册 Application

在 Manifest.xml 中注册 Application : 在 <application> 标签中添加 android:name 属性, 属性值就是 自定义 MyApplication 路径;

-- 示例 :

  1. <application android:name="cn.org.octopus.application.MyApplication" >

2. 保存崩溃日志到文件

(1) UncaughtExceptionHandler 简介

UncaughtExceptionHandler 未捕获异常处理类简介 :

-- 线程相关 : 每个线程都有一个未捕获异常处理类;

使用自定义 UncaughtExceptionHandler 类代替 线程默认的 UncaughtExceptionHandler 类 :

  1. /*
  2. * Android 中每个线程都有其指定的 未捕获异常处理类 UncaughtExceptionHandler
  3. * 这里我们将该线程的异常处理类获取, 将其赋予本类中的成员变量, 将本类设置为线程默认的 未捕获异常处理类
  4. * 这样就相当与在 UncaughtExceptionHandler 的外层包装了一层, 我们可以对未捕获的异常信息进行任何操作
  5. */
  6. //获取系统默认的UncaughtException处理器
  7. mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  8. //设置该CrashHandler为程序的默认处理器
  9. Thread.setDefaultUncaughtExceptionHandler(this);

函数驱动动力 :

-- 回调方法 : 当出现了未捕获异常时, 在崩溃前会回调 uncaughtException() 方法, 该方法驱动其它方法运行;

-- 详细方法 public void uncaughtException(Thread thread, Throwable ex);

-- 重写方法 : 在方法中使用 用户自行处理 Throwable ex 抛出的异常, 如果用户没有处理, 使用默认的异常处理器;

  1. if (!handleException(ex) && mDefaultHandler != null) {
  2. //如果用户没有处理则让系统默认的异常处理器来处理
  3. mDefaultHandler.uncaughtException(thread, ex);
  4. }

(2) 收集相关参数信息

获取设备信息, 异常信息 : Field[] fields = Build.class.getDeclaredFields();

-- 将获取的信息转为字符串 :

  1. /*
  2. * 该字段封装了很多信息
  3. * 包括 : 设备信息 异常信息等
  4. */
  5. Field[] fields = Build.class.getDeclaredFields();
  6. for (Field field : fields) {
  7. try {
  8. field.setAccessible(true);
  9. infos.put(field.getName(), field.get(null).toString());
  10. Log.d(TAG, field.getName() + " : " + field.get(null));
  11. } catch (Exception e) {
  12. Log.e(TAG, "an error occured when collect crash info", e);
  13. }
  14. }

(3) 在 Application 中注册该类

Application 中注册 : 具体内容请详看代码;

  1. //注册异常日志处理类
  2. CrashHandler crashHandler = CrashHandler.getInstance();
  3. //初始化异常日志处理类
  4. crashHandler.init(getApplicationContext());

3. 监听 Activity 生命周期

(1) 自定义 ActivityLifecycleCallbacks 接口实现类

自定义 ActivityLifecycleCallbacks 类 :

  1. /**
  2. * Activity 生命周期监听
  3. * @author octopus
  4. *
  5. */
  6. class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks{
  7. @Override
  8. public void onActivityCreated(Activity activity,
  9. Bundle savedInstanceState) {
  10. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityCreated");
  11. }
  12. @Override
  13. public void onActivityStarted(Activity activity) {
  14. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityStarted");
  15. }
  16. @Override
  17. public void onActivityResumed(Activity activity) {
  18. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityResumed");
  19. }
  20. @Override
  21. public void onActivityPaused(Activity activity) {
  22. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityPaused");
  23. }
  24. @Override
  25. public void onActivityStopped(Activity activity) {
  26. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityStopped");
  27. }
  28. @Override
  29. public void onActivitySaveInstanceState(Activity activity,
  30. Bundle outState) {
  31. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivitySaveInstanceState");
  32. }
  33. @Override
  34. public void onActivityDestroyed(Activity activity) {
  35. Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityDestroyed");
  36. }
  37. }

在 onCreate() 方法中注册该类 :

  1. //注册 Activity 声明周期监听器
  2. registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());

(2) 执行效果

执行效果 :

  1. octopus@octopus:~$ adb logcat | grep cn.org.octopus.application.activity.life
  2. I/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityCreated
  3. I/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityStarted
  4. I/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityResumed
  5. I/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityPaused
  6. I/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityStopped
  7. I/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityDestroyed


博客地址 
http://blog.csdn.net/shulianghan/article/details/40737419

代码下载 : Android 应用 Application 经典用法;

-- Github : https://github.com/han1202012/ApplicationDemo

-- CSDN : http://download.csdn.net/detail/han1202012/8127247

Application 使用分析的更多相关文章

  1. 【Android 应用开发】 Application 使用分析

    博客地址 : http://blog.csdn.net/shulianghan/article/details/40737419 代码下载 : Android 应用 Application 经典用法; ...

  2. Rest之路 -- 从第二个Rest application里面分析 Rest 方法

    引言 在此之前,我们实现了第一个Rest application,通过分析她,我们了解了 Rest 程序的基本要素:这里,我们将会对第一个 Rest application 的功能进行扩充(实现 CR ...

  3. Application 效能分析有妙招 — 使用 perf 走天下(转载)

    转载:http://tech.mozilla.com.tw/posts/1803/application-%E6%95%88%E8%83%BD%E5%88%86%E6%9E%90-%E4%BD%BF% ...

  4. Java application 性能分析分享

    性能分析的主要方式 监视:监视是一种用来查看应用程序运行时行为的一般方法.通常会有多个视图(View)分别实时地显示 CPU 使用情况.内存使用情况.线程状态以及其他一些有用的信息,以便用户能很快地发 ...

  5. Android application framework 分析[in process]

    application activity application service application UI system application sdk tool JVM 1 activity t ...

  6. 转 LoadRunner 技巧之协议分析

    在做性能测试的时候,协议分析是困扰初学者的难题,选择错误的协议会导致Virtual User Generator 录制不到脚本:或录制的脚本不完整,有些应用可能需要选择多个协议才能完整的记录 客户端与 ...

  7. LoadRunner ---协议分析

    在做性能测试的时候,协议分析是困扰初学者的难题,选择错误的协议会导致Virtual User Generator 录制不到脚本:或录制的脚本不完整,有些应用可能需要选择多个协议才能完整的记录 客户端与 ...

  8. LoadRunner 技巧之协议分析(五)

    在做性能测试的时候,协议分析是困扰初学者的难题,选择错误的协议会导致Virtual User Generator 录制不到脚本:或录制的脚本不完整,有些应用可能需要选择多个协议才能完整的记录 客户端与 ...

  9. 转:LoadRunner自带的协议分析工具

    在做性能测试的时候,协议分析是困扰初学者的难题,不过优秀的第三方协议分析工具还是挺多的,如:MiniSniffer .Wireshark .Ominpeek 等:当然他们除了帮你分析协议之外,还提供其 ...

随机推荐

  1. Clang调试deadcode思路

    首先描述下我的环境:Ubuntu16.04 llvm4.0 clang4.0全部使用源码安装方式 Clang的根目录,位于llvm-src下边的tools目录下. 因为需要找到真正的开关,下边我描述下 ...

  2. Seeker:一款可获取高精度地理和设备信息的工具分析

    Seeker是一款可以获取高精度地理和设备信息的工具.其利用HTML5,Javascript,JQuery和PHP来抓取设备信息,以及Geolocation接口实现对设备高精度地理位置的获取. See ...

  3. 使用shell脚本自动打包上传 fir.im

    http://blog.csdn.net/wang631106979/article/details/52299083

  4. 14、Nginx四层负载均衡

    1.Nginx四层负载均衡基本概述 1.1.什么是四层负载均衡 四层负载均衡基于传输层协议包来封装的(如:TCP/IP),那我们前面使用到的七层是指的应用层,它的组装在四层基础之上,无论四层还是七层都 ...

  5. python连接activemq

    介绍 activeMQ是一款消息队列,关于消息队列是什么这里就不再介绍了,这里只介绍如何使用python去连接activemq进行消息的发送和接收.既然都用python去连接了,那么对于消息队列是什么 ...

  6. 小黄车ofo法人被限制出境,它究竟还能撑多久?

    因为季节的原因,现在正是骑车的好时候,而且北京也开通了一条自行车的专用路.但就是在这么好的时候,我们发现,路边的小黄车却越来越少了,而且它的麻烦还不断! ofo法人被限制出境 6月12日消息,据上海市 ...

  7. RAID原理详解

    RAID 0(stripe,条带化存储):在RAID级别中最高的存储性能. 原理:是把连续的数据分散到多个磁盘上存取,系统有数据请求就可以被多个磁盘并行的执行,每个磁盘执行属于他自己的那部分数据请求. ...

  8. usb server

    usb server 是通道型的,驱动在客户端安装 服务端不需要驱动

  9. 最长回文子串(动规,中心扩散法,Manacher算法)

    题目 leetcode:5. Longest Palindromic Substring 解法 动态规划 时间复杂度\(O(n^2)\),空间复杂度\(O(n^2)\) 基本解法直接看代码 class ...

  10. fwrite()

    fwrite(),最好写strlen()个字节,否则可能有乱码