├── .gitignore ├── Android中的冷门知识点汇总 └── Android中的冷门知识汇总.md ├── Android开发遇到的坑汇总 └── Android开发遇到的坑.md ├── LICENSE ├── README.md ├── codes └── data_util │ └── com │ └── lzw │ └── data.util │ ├── CharsetNameTypes.java │ ├── DataUtil.java │ └── Test.java ├── design_patterns ├── README.md └── src │ └── com │ └── lzw │ └── part1_creation_mode │ ├── README.md │ └── builder │ ├── chainsaw │ ├── ChainsawBuilder.java │ ├── ChainsawBuilderImpl.java │ ├── ChainsawBuilderImpl2.java │ ├── Chainsaws.java │ ├── HardwareStoreBoss.java │ └── Test.java │ └── chainsaw2 │ ├── ChainsawBuilder.java │ ├── ChainsawBuilderImpl2.java │ ├── Chainsaws.java │ └── Test.java ├── github_README └── README文档的规范写法.md ├── interview ├── answers │ ├── HR提出的面试问题参考解答.md │ ├── 部分面试题解答.md │ └── 高端技术面试题参考答案和示例代码 │ │ ├── code │ │ ├── BinaryTreeDemo.java │ │ ├── BubbleSortDemo.java │ │ ├── HeapSort2Demo.java │ │ ├── HeapSortDemo.java │ │ └── QuickSortDemo.java │ │ └── 参考答案.md ├── contents │ ├── Android面试题.md │ ├── java面试题.md │ ├── 混合开发技术面试题.md │ ├── 非技术性问题&HR问题汇总.md │ └── 高端技术面试题.md └── summary.md ├── pic ├── Sorting-algorithm.png ├── architucture.png ├── collection.png ├── donation.png ├── hashmap.jpg ├── http.png └── logo.png ├── 双击back退出app └── 双击back退出app.md └── 国内BATH等大厂开源的安卓有关的库 └── 全面总结国内BATH等大厂开源的安卓有关的库.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | 43 | # Keystore files 44 | *.jks 45 | 46 | # External native build folder generated in Android Studio 2.2 and later 47 | .externalNativeBuild 48 | 49 | # Google Services (e.g. APIs or Firebase) 50 | google-services.json 51 | 52 | # Freeline 53 | freeline.py 54 | freeline/ 55 | freeline_project_description.json 56 | -------------------------------------------------------------------------------- /Android中的冷门知识点汇总/Android中的冷门知识汇总.md: -------------------------------------------------------------------------------- 1 | 本文转载自:https://zhuanlan.zhihu.com/p/30879859 2 | 3 | # 四大组件相关: 4 | 5 | 1.启动一个Activity,在应用进程至少需要两个Binder线程。 6 | 7 | 2.启动一个launchMode为singleTask的Activity,它并不一定会运行在新的Activity栈中。 8 | 9 | 3.两个不同应用的Activity,可以运行在同一个Activity栈中。 10 | 11 | 4.同一个应用进程中的所有Activity,共享一个WindowSession。 12 | 13 | 5.弹出一个AlertDialog,不一定需要Activity级别的Context,而且任何地方都有办法弹出一个AlertDialog,只要是在Application的attachBaseContext之后。 14 | 15 | 下面是一个简单的demo演示: 16 | 17 | 首先看DemoApplication,然后看Alert类: 18 | 19 | > 在Application中初始化: 20 | 21 | import android.app.Application; 22 | 23 | public class DemoApplication extends Application { 24 | @Override 25 | public void onCreate() { 26 | Alert.alertAnyWhere(); 27 | super.onCreate(); 28 | } 29 | } 30 | 31 | 32 | > 下面这个类是对AlertDialog的封装类: 33 | 34 | 35 | import android.app.AlertDialog; 36 | import android.content.Context; 37 | import android.content.DialogInterface; 38 | import android.os.Build; 39 | import android.os.Handler; 40 | import android.os.Looper; 41 | import android.view.WindowManager; 42 | import java.lang.reflect.Method; 43 | 44 | public class Alert { 45 | 46 | public static void alertDialog() { 47 | Context mAppContext = null; 48 | try { 49 | Class clazz = Class.forName("android.app.ActivityThread"); 50 | Method method = clazz.getDeclaredMethod("currentApplication", new Class[0]); 51 | mAppContext = (Context) method.invoke(null, new Object[0]); 52 | } catch (Throwable e) { 53 | e.printStackTrace(); 54 | return; 55 | } 56 | 57 | AlertDialog.Builder builder = new AlertDialog.Builder(mAppContext); 58 | builder.setTitle("Hi") 59 | .setMessage("Hello World"); 60 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 61 | @Override 62 | public void onClick(DialogInterface dialog, int which) { 63 | dialog.dismiss(); 64 | } 65 | }) 66 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 67 | @Override 68 | public void onClick(DialogInterface dialog, int which) { 69 | } 70 | }); 71 | AlertDialog dialog = builder.create(); 72 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 73 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST); 74 | } else { 75 | dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); 76 | } 77 | dialog.show(); 78 | } 79 | 80 | 81 | private static Handler handler; 82 | 83 | public static void alertAnyWhere() { 84 | if (Looper.myLooper() == Looper.getMainLooper()) { 85 | alertDialog(); 86 | } else { 87 | if (handler == null) { 88 | handler = new Handler(Looper.getMainLooper()); 89 | } 90 | handler.post(new Runnable() { 91 | @Override 92 | public void run() { 93 | alertDialog(); 94 | } 95 | }); 96 | } 97 | } 98 | 99 | } 100 | 101 | 102 | 103 | 104 | 105 | 6.可以通过设置Activity主题android.R.style.Theme_NoDisplay,来启动一个不显示的Activity,在某些需要过渡的地方很实用。 106 | 107 | 7.Activity、Service、Receiver在没有配置intent-filter的action属性时,exported默认为false,配置了intent-filter的action属性时,exported默认为true。稍有不慎,很可能埋下越权、Intent攻击等安全隐患。 108 | 109 | 8.当从最近使用应用列表中移除某个App时,四大组件只有Service拥有神奇的onTaskRemoved回调,但是并不一定回调,还与stopWithTask属性等有关。 110 | 111 | 9.四大组件都运行在主线程,是因为它们在ActityThread中(或Instrumentation)实例化;它们的生命周期也运行在主线程,是因为通过ActivityThread.H将消息从Binder线程发送到主线程,然后执行回调。 112 | 113 | 10.TaskStackBuilder的出现基本上解决了所有构造Activity回退栈的问题。 114 | 115 | 11.ContentProvider的onCreate()方法先于Application的onCreate()方法执行,晚于Application的attachBaseContext()方法,所以在ContentProvider的onCreate()时候也是有办法弹出一个AlertDialog的(参考5)。 116 | 117 | 12.BroadCastReceiver回调onReceive(Context context,Intent intent)中的context类型各种场景相差很大,静态注册的receiver回调的Context都是ReceiverRestrictedContext,动态注册的receiver有可能是Activity或Application。 118 | 119 | 13.ServiceRecord和BroadcastRecord自身就是Binder。 120 | 121 | 14.同一个provider组件名,可能对应多个provider。 122 | 123 | 124 | 125 | # Handler、Message相关: 126 | 127 | 1.MessageQueue.addIdleHandler可以用来在线程空闲的时候,完成某些操作,比较适合那种需要在将来执行操作,却又不知道需要指定多少延迟时间的操作。 128 | 129 | 2.Message.what尽量不要设置成0,因为postRunnable的方式会生成Message.what为0的消息,如果删除了what为0的Message,也会将runnable方式创建的Message删掉。 130 | 131 | 3.Handler可以设置同步异步(默认是同步的),他们的区别在于异步不会被Barrier阻塞,而同步会被阻塞。 132 | 133 | 4.Handler的消息分发流程是如果Message的callback不为空,通过callback处理,如果Handler的mCallback不为空,通过mCallback来处理,如果前两个都为空,才调用handleMessage来处理。在DroidPlugin中,便是利用ActivityThread.H的这一特性,拦截了部分消息,实现Activity的插件化。 134 | 135 | 5.Java层和Native层Looper、MessageQueue的创建时序,Java层Looper—>Java层MessageQueue—>Native层NativeMessageQueue—>Native层Looper。 136 | 137 | 6.Java层通过Handler去发送消息,而Native层是通过Looper发消息。 138 | 139 | 140 | 141 | # Window、View相关: 142 | 143 | 1.硬件加速在Window级只能开不能关,View级只能关不能开。 144 | 145 | 2.自android2.3删除MidWindow后,PhoneWindow成了Window的唯一实现类。 146 | 147 | 3.WMS管理Window的过程中涉及4个Binder,应用进程只有ViewRootImpl.W一个Binder服务端。 148 | 149 | 4.MotionEvent、KeyEvent、DragEvent等具有相似的链式缓存,类似Message。 150 | 151 | 5.在View的状态保存、恢复过程中,ActionBar中所有View共享一个SparseArray容器,ContentView中所有View共享一个SparseArray容器。当前获取焦点的View会额外存储。 152 | 153 | 6.设置ViewTreeObserver的系列监听方法需要确保View在attachToWindow之后,否则可能因为add监听和remove监听不是作用于同一个对象而引起内存泄漏等。 154 | 155 | 156 | 157 | # Binder、IPC、进程等相关 158 | 159 | 1.可以通过文件锁来实现进程间互斥(参考:RePlugin),在处理某些只需要单进程执行的任务时很实用。 160 | 161 | 2.Binder设计架构中,只有Binder主线程是由本进程主动创建,Binder普通线程都是由Binder驱动根据IPC通信需求被动创建。 162 | 163 | 3.oneway与非oneway,都需要等待Binder Driver的回应消息(BR_TRANSACTION_COMPLETE),区别在于oneway不用等待BR_REPLY消息。 164 | 165 | 4.mediaserver和servicemanager的主线程都是binder线程,但system_server的主线程不是Binder线程,system_server主线程的玩法跟应用进程一样。 166 | 167 | 5.同一个BpBinder可以注册多个死亡回调,但Kernel只允许注册一次死亡通知。 168 | 169 | 6.应用进程由Zygote进程孵化而来,在它真正成为应用进程之前,系统通过抛异常的方式来清理栈帧,并反射调用ActivityThread的main方法。 170 | 171 | 7.在Binder通信的过程中,数据是从发起通信进程的用户空间直接写到目标进程内核空间,内核空间的数据释放是由用户空间控制的。 172 | 173 | -------------------------------------------------------------------------------- /Android开发遇到的坑汇总/Android开发遇到的坑.md: -------------------------------------------------------------------------------- 1 | # Android开发遇到的坑汇总 2 | 3 | ---- 4 | 5 | #### 1、Toolbar去除标题与返回键间的间距 6 | 7 | 给toolbar加上以下属性: 8 | 9 | app:navigationIcon="@drawable/icon_back" //这是设置返回键图标,这是必不可少的。 10 | app:contentInsetStartWithNavigation="0dp" 11 | 12 | 13 | 为了保险起见,建议加上这两个属性: 14 | 15 | app:contentInsetLeft="0dp" 16 | app:contentInsetStart="0dp" 17 | 18 | 完整的示范如下: 19 | 20 | 34 | 35 | #### 2、RecyclerView常见的一些坑 36 | 37 | > 问题1、ScrollView(或RecyclerView1)嵌套RecyclerView2,结果内部的RecyclerView2会自动的滑动至顶部.(一般情况下不推荐嵌套使用具有滑动功能的View) 38 | 两种解决办法: 39 | 40 | **方法一** 让内部Recyclerview去除焦点,父布局里获得焦点。具体如下: 41 | 42 | 给内部的Recyclerview设置以下代码: 43 | 44 | recyclerview.setFocusableInTouchMode(false); 45 | recyclerview.requestFocus(); 46 | 47 | 比如父布局的一个textview。 48 | 49 | textview.setFocusableInTouchMode(true); 50 | textview.requestFocus(); 51 | 52 | **方法二** 在布局里面加相关属性: 53 | 54 | 内部的Recyclerview加这个属性: 55 | 56 | android:overScrollMode="never" 57 | 父布局覆盖子View获取焦点,加这个属性: 58 | 59 | android:descendantFocusability="blocksDescendants" 60 | 61 | > 问题2、RecyclerView 高度设置wrap_content 不显示的解决: 62 | 63 | 给RecyclerView的高度设置为`wrap_content`,结果整个模块什么也不显示,这是RecyclerView兼容包的bug,`23.2.0后`官方已经修复了。 64 | 65 | 【解决方式】在gradle里设置用23.2.0及以上的RecyclerView版本: 66 | 67 | compile 'com.android.support:recyclerview-v7:23.2.0' 68 | 69 | 如果修改后重新build时报了其他奇怪的错,可以试试把以下相关兼容包也升级一下: 70 | 71 | compile 'com.android.support:cardview-v7:23.2.0' 72 | compile 'com.android.support:appcompat-v7:23.2.0' 73 | compile 'com.android.support:design:23.2.0' 74 | 75 | > 问题3、RecyclerView 中的item布局宽度设置match_parent属性失效的问题解决: 76 | 77 | //这里为了解决RecyclerView不能撑满全屏的问题,这里layoutManager不管你布局里是否设置,都不能解决问题,所以需要在代码里`重新设置MATCH_PARENT` 78 | 79 | LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()) { 80 | @Override 81 | public RecyclerView.LayoutParams generateDefaultLayoutParams() { 82 | return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 83 | ViewGroup.LayoutParams.WRAP_CONTENT); 84 | } 85 | }; 86 | layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 87 | recyclerview.setLayoutManager(layoutManager); 88 | 关于为什么`RecyclerView 中的item布局宽度设置match_parent属性失效`的原因详解可以参考这篇博客,有详细介绍:[https://blog.csdn.net/overseasandroid/article/details/51840819](https://blog.csdn.net/overseasandroid/article/details/51840819) 89 | 90 | #### 3、NumberFormatException 91 | 92 | 起因是Bugly上报了一个错误: 93 | 94 | #main(1) 95 | java.lang.NumberFormatException 96 | Invalid float "0,00" 97 | 98 | 说是我格式化“0,00”这样的一个字符串。出错的地方的代码大致如下: 99 | 100 | String.format("%.2f", number); 101 | 102 | 经排查排除了格式字符串的问题后,最后发现是格式化的问题:`在不指定Locale时,是跟随系统语言`。在法语、德语、意大利语的语言中,格式化小数是逗号的。所以解决方法,指定一下语言: 103 | 104 | String.format(Locale.CHINA, "%.2f", number); 105 | 106 | #### 4、SecurityException 107 | 108 | 在之前项目中做了6.0的动态权限后,Bugly报错如下,而且报错的全部都是6.0的手机: 109 | 报错的意思翻译一下是:没有动态授权`CHANGE_NETWORK_STATE`和`WRITE_SETTINGS`权限。 110 | 111 | 查了一下,找到了问题。发现是6.0的一个bug,在部分6.0上CHANGE_NETWORK_STATE权限获取不到,那么只能去获取WRITE_SETTINGS这个权限了。这个问题已经在6.0.1修复了。关于这个bug详细讲解可以查看博客 [Android M WRITE_SETTINGS权限的一个BUG](https://www.jianshu.com/p/bab716584316) 112 | 113 | > 解决方式1 114 | > 115 | > 既然是6.0的问题,我们可以对6.0进行单独处理。抛出异常处或者在使用`CHANGE_NETWORK_STATE`权限前跳转到系统设置页去设置。 116 | 117 | if(Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { 118 | if (!Settings.System.canWrite(context)) { 119 | Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); 120 | intent.setData(Uri.parse("package:" + context.getPackageName())); 121 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 122 | context.startActivity(intent); 123 | } 124 | } 125 | 126 | > 解决方式2 127 | > 128 | > 以上方式每次都要手动去设置,很麻烦,可以看看这篇博文,写的很仔细 [Android 6 完美解决 WRITE_SETTINGS 权限设置问题](https://www.jianshu.com/p/0b880871b887) 129 | 130 | #### 5、在做6.0动态权限时,如果有申请相机权限时,应该保证`Manifest.permission.CAMERA`和`Manifest.permission.WRITE_EXTERNAL_STORAGE`权限同时申请,不要漏掉后者。 131 | 132 | #### 6、使用Glide时,注意对传入的Acticity与Fragment进行判断,避免传入已经销毁Acticity,造成`IllegalArgumentException`异常。可以参考这篇[Glide类似You cannot start a load for a destroyed activity异常简单分析](https://blog.csdn.net/loners_/article/details/73521968) 133 | 134 | #### 7、不要在Android的Application对象中缓存数据,具体的可以参考[这篇文章](https://www.jianshu.com/p/83f0046bc310) 135 | 136 | #### 8、关于资源目录引用问题(经常会遇到的) 137 | 138 | //这个是正确使用方式 139 | textView.setTextColor(getResources().getColor(R.color.colorAccent)); 140 | //下面这个报错 141 | textView.setTextColor(R.color.colorAccent); 142 | 143 | > 分析:setTextColor方法的参数是 @ColorInt类型的,使用`getResources().getColor(R.color.colorAccent)`返回的是` @ColorInt`类型的int值,直接使用`R.color.colorAccent`的方式属于`@ColorRes`类型的int值。 144 | 145 | 146 | #### 9、fragment的坑(这是一个大坑,很多人都遇到过的) 147 | 148 | > 问题1、getActivity()空指针 149 | > 150 | > 问题2、异常:Can not perform this action after onSaveInstanceState 151 | > 152 | > 问题3、Fragment重叠异常—–如何正确使用hide、show? 153 | 154 | > 问题4、Fragment嵌套的那些坑? 155 | 156 | > 问题5、不靠谱的出栈方法remove() 157 | 158 | > 问题6、多个Fragment同时出栈的那些深坑BUG 159 | 160 | > 问题7、超级深坑 Fragment转场动画 161 | 162 | 关于这些坑的具体介绍可以看博客[Fragment全解析系列(一):那些年踩过的坑](https://www.jianshu.com/p/d9143a92ad94) 163 | 164 | 解决方案,可以看这个库 [Fragmentation](https://github.com/YoKeyword/Fragmentation) 165 | 166 | ---- 167 | 168 | > 参考博文: 169 | 170 | * https://blog.csdn.net/qq_17766199/article/details/52661363 171 | * https://blog.csdn.net/qq_17766199/article/details/79941199 172 | * https://blog.csdn.net/geolo/article/details/7058515 173 | 174 | ---- 175 | 176 | > **【说明】我这个总结主要是针对平时开发遇到的问题的一个汇总,由于实际开发项目不同,用到的技术和接触的一些东西也不一样,所以可能这里找不到你遇到的坑,不过没关系,我发现了一个github总结的很全面,有基础的使用,有NDK遇到的坑,有framework层的坑,有linux有关的坑等。。。如果对你有帮助的话,有兴趣的也可以过去看一下:[android-issues](https://github.com/ayyb1988/android-issues)** 177 | 178 | ---- 179 | 180 | #### 有什么问题,欢迎大家提出,如果你也遇到了其他的坑,也欢迎提交给我,我会把它收集在这里,让大家都来学习一下,避免少走弯路。 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [AWeiLoveAndroid] [AWeiLoveAndroid] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CommonDevKnowledge 2 | 3 | 4 |

5 | 6 | 7 | 8 |

9 | 10 |

11 | 12 | 13 | 14 | 15 | 16 | 17 | 酷玩Android你最牛 18 |

19 | 20 | ---- 21 | 22 | ## 介绍 23 | 这个库主要是一些常用的Android开发的一些技能点汇集,有填坑总结,有面试总结,有冷门知识点总结等,总之Android开发有关的知识点都会涵盖到。 24 | 25 | Android只是太多太杂乱,很多人都不知道从何学起。也一些东西我们开发中经常会遇到,于是我就把常用知识点汇集在一起,方便大家平时开发。 26 | 27 | 我会不定期更新,欢迎大家投稿和提意见,提issues请点击:。如果你遇到一些好用的好玩的开发知识点,欢迎pull request,请点击:。 28 | 29 | ---- 30 | 31 | ## 目录结构 32 | 33 | > ### 1、面试&职场 34 | 35 | :fire: :one: **[BAT大公司面试题集锦](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/summary.md)** 36 | 这一部分同步发布在我的简书博客,文章地址:[https://www.jianshu.com/p/c70989bd5f29](https://www.jianshu.com/p/c70989bd5f29) 37 | 38 | > ### 2、开发文档&开发规范 39 | 40 | :fire: :one: **[README文档的规范写法](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/github_README/README%E6%96%87%E6%A1%A3%E7%9A%84%E8%A7%84%E8%8C%83%E5%86%99%E6%B3%95.md)** 41 | 这一部分同步发布在我的简书博客,文章地址:[https://www.jianshu.com/p/813b70d5b0de](https://www.jianshu.com/p/813b70d5b0de) 42 | 43 | > ### 3、Android技能点整理 44 | 45 | :point_right: :one: **[Android开发遇到的坑汇总](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/Android%E5%BC%80%E5%8F%91%E9%81%87%E5%88%B0%E7%9A%84%E5%9D%91%E6%B1%87%E6%80%BB/Android%E5%BC%80%E5%8F%91%E9%81%87%E5%88%B0%E7%9A%84%E5%9D%91.md)** 46 | 47 | :fire: :one: **[屏幕适配](https://www.jianshu.com/c/b5d1ce82ee2d)** 48 | 49 | :fire: :one: **[Android常用工具类(超级全面,值得收藏)](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/codes/data_util/com/lzw/data.util/DataUtil.java)** 50 | 51 | :point_right: :one: **[Android中的冷门知识点汇总](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/Android%E4%B8%AD%E7%9A%84%E5%86%B7%E9%97%A8%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB/Android%E4%B8%AD%E7%9A%84%E5%86%B7%E9%97%A8%E7%9F%A5%E8%AF%86%E6%B1%87%E6%80%BB.md)** 52 | 53 | :pencil: :one: **[双击back退出app](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/%E5%8F%8C%E5%87%BBback%E9%80%80%E5%87%BAapp/%E5%8F%8C%E5%87%BBback%E9%80%80%E5%87%BAapp.md)** 54 | 55 | :pencil: :one: **应用角标的实现(待完善)** 56 | 57 | :pencil: :one: **利用原生api实现分享等功能(待完善)** 58 | 59 | :pencil: :one: **二维码处理(待完善)** 60 | 61 | > ### 4、Java知识点解读 62 | 63 | **设计模式:** [Java23种设计模式](design_patterns) 64 | 65 | 66 | > ### 5、开源库整理 67 | 68 | :fire: :one: **[全面总结国内BATH等大厂开源的安卓有关的库](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/%E5%9B%BD%E5%86%85BATH%E7%AD%89%E5%A4%A7%E5%8E%82%E5%BC%80%E6%BA%90%E7%9A%84%E5%AE%89%E5%8D%93%E6%9C%89%E5%85%B3%E7%9A%84%E5%BA%93/%E5%85%A8%E9%9D%A2%E6%80%BB%E7%BB%93%E5%9B%BD%E5%86%85BATH%E7%AD%89%E5%A4%A7%E5%8E%82%E5%BC%80%E6%BA%90%E7%9A%84%E5%AE%89%E5%8D%93%E6%9C%89%E5%85%B3%E7%9A%84%E5%BA%93.md)** 这一部分同步发布在我的简书博客,文章地址:[https://www.jianshu.com/p/2a6c806ba2fc](https://www.jianshu.com/p/2a6c806ba2fc) 69 | 70 | ---- 71 | 72 | # 赞赏 73 | 74 | 如果这个库对您有很大帮助,您愿意支持这个项目的进一步开发和这个项目的持续维护。你可以免费扫描下面的二维码,让我喝一杯咖啡或啤酒。非常感谢您的捐赠。谢谢! 75 | 76 | ![](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/pic/donation.png?raw=true) 77 | 78 | ---- 79 | 80 | # 联系我 81 | 82 | ### ● 微信: 83 | 84 | > 欢迎关注我的微信:`wei_xing_tian_xia` 85 | 86 | ### ● 微信群: 87 | 88 | > 由于大家学习热情太高,**微信群目前不能扫码加入了,麻烦大家想进微信群的朋友们,加我微信拉你进群。** 89 | 90 | ### ● 微信公众号: 91 | 92 | > 我的微信公众号也开通了,欢迎大家关注:`Flutter那些事`,扫码就可以关注了,专注于研究Flutter的公众号,最新最全面的系统的Flutter干货总结都在这个公众号,欢迎关注。 93 | 94 | ![我的微信公众号](https://github.com/AweiLoveAndroid/Flutter-learning/blob/master/pics/%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.jpg?raw=true) 95 | 96 | 97 | ### ● QQ群: 98 | 99 | > 2千人QQ群,**Android学习开发交流群,QQ群号:280891494**, 欢迎大家加入讨论。 100 | 101 | **欢迎大家在issues里面提出宝贵的建议,如果你有更多面试题,欢迎在issues里面提供,同时也欢迎各位积极作答。帮助别人的同时也是对自己知识点的巩固和提高。** 102 | 103 | ### ● 个人博客: 104 | 105 | [简书博客 AWeiLoveAndroid](https://www.jianshu.com/u/f408bdadacce) 106 | 107 | [掘金博客 AWeiLoveAndroid](https://juejin.im/user/5a07c6c0f265da430a501017) 108 | 109 | ---- 110 | 111 | # Licence 112 | 113 | ``` 114 | Copyright 2018,AWeiLoveAndroid,阿韦 115 | 116 | Licensed under the Apache License, Version 2.0 (the "License"); 117 | you may not use this file except in compliance with the License. 118 | You may obtain a copy of the License at 119 | 120 | http://www.apache.org/licenses/LICENSE-2.0 121 | 122 | Unless required by applicable law or agreed to in writing, software 123 | distributed under the License is distributed on an "AS IS" BASIS, 124 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125 | See the License for the specific language governing permissions and 126 | limitations under the License. 127 | ``` 128 | -------------------------------------------------------------------------------- /codes/data_util/com/lzw/data.util/CharsetNameTypes.java: -------------------------------------------------------------------------------- 1 | package com.lzw.data.util; 2 | 3 | /** 4 | * @desp 编码类型 5 | *

版权归作者LZW所有,转载或使用请注明注明GitHub链接,谢谢合作!

6 | * @author LZW 7 | * @version 1.0 8 | * @date 2019-05-01 9 | * @website https://github.com/AweiLoveAndroid/CommonDevKnowledge 10 | * @mail lzw20099002@126.com 有任何疑问欢迎发邮件 或者 加微信咨询(本开源库README.md有介绍) 11 | * 12 | */ 13 | public interface CharsetNameTypes { 14 | public static final String CHARSETNAME_UTF8 = "UTF-8"; 15 | public static final String CHARSETNAME_UTF16 = "UTF-16"; 16 | public static final String CHARSETNAME_UTF32 = "UTF-32"; 17 | public static final String CHARSETNAME_UNICODE = "UNICODE"; 18 | public static final String CHARSETNAME_GBK = "GBK"; 19 | public static final String CHARSETNAME_GB2312 = "GB2312"; 20 | public static final String CHARSETNAME_GB18030 = "GB18030"; 21 | public static final String CHARSETNAME_ASCII = "ASCII"; 22 | public static final String CHARSETNAME_ISO_8859_1 = "ISO-8859-1"; 23 | } 24 | -------------------------------------------------------------------------------- /codes/data_util/com/lzw/data.util/DataUtil.java: -------------------------------------------------------------------------------- 1 | package com.lzw.data.util; 2 | 3 | import com.sun.istack.internal.NotNull; 4 | 5 | import java.nio.ByteBuffer; 6 | import java.nio.CharBuffer; 7 | import java.nio.charset.Charset; 8 | import java.nio.charset.StandardCharsets; 9 | 10 | /** 11 | * @desp 数据工具类 (史上最完整的工具类,值得收藏) 12 | *

byte int short long float double char String 8种类型相互转换 以及不同进制相关转换的工具类

13 | *

版权归作者LZW所有,转载或使用请注明GitHub链接,谢谢合作!

14 | * @author LZW 15 | * @version 1.0 16 | * @date 2019-05-01 17 | * @website https://github.com/AweiLoveAndroid/CommonDevKnowledge 18 | * @mail lzw20099002@126.com 有任何疑问欢迎发邮件 或者 加微信咨询(本开源库README.md有介绍) 19 | * 20 | */ 21 | public class DataUtil implements CharsetNameTypes { 22 | 23 | /** 24 | * 用于建立十六进制字符的输出的小写字符数组 25 | */ 26 | private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', 27 | '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 28 | 29 | /** 30 | * 用于建立十六进制字符的输出的大写字符数组 31 | */ 32 | private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', 33 | '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 34 | 35 | 36 | //////////////////////////////////////////////////////////////////////////////// 37 | /// 38 | /// byte 和 byte 数组转换成其它类型 39 | /// byte 取值范围:-128(-2^7) 到 127(2^7-1) 40 | //////////////////////////////////////////////////////////////////////////////// 41 | 42 | /** 43 | * byte 转成int 44 | * 45 | * @param byteNumber 46 | * @return

{@link #byte2Int2(byte)}

47 | */ 48 | public static int byte2Int(@NotNull byte byteNumber) { 49 | // Java的byte是有符号,通过 &0xFF转为无符号 50 | return byteNumber & 0xFF; 51 | } 52 | 53 | 54 | /** 55 | * byte 转成int 56 | * 57 | * @param byteNumber 58 | * @return

{@link #byte2Int(byte)}

59 | */ 60 | public static int byte2Int2(@NotNull byte byteNumber) { 61 | return Integer.parseInt(byte2String(byteNumber)); 62 | } 63 | 64 | 65 | /** 66 | * byte数组转成short 67 | * 68 | * @param byteNumber byte数组 69 | * @return short类型 70 | * 该方法在某些情况会有精度丢失以及bug, 请谨慎使用。 71 | */ 72 | public static Short byte2Short(@NotNull byte byteNumber) { 73 | return (short) byteNumber; 74 | } 75 | 76 | 77 | public static long byte2Long(@NotNull byte byteNumber) { 78 | return string2Long(byte2String(byteNumber)); 79 | } 80 | 81 | public static float byte2Float(@NotNull byte byteNumber) { 82 | return string2Float(byte2String(byteNumber)); 83 | } 84 | 85 | public static double byte2Double(@NotNull byte byteNumber) { 86 | return string2Double(byte2String(byteNumber)); 87 | } 88 | 89 | // public static char byte2Char(@NotNull byte byteNumber) { 90 | //// return string2c(byte2String(byteNumber)); 91 | //// } 92 | 93 | 94 | public static String byte2String(@NotNull byte byteNumber) { 95 | return String.valueOf(byteNumber); 96 | } 97 | 98 | /** 99 | * byte数组转成short 100 | * 101 | * @param byteNumber byte数组 102 | * @return short类型 103 | */ 104 | public static short byte2Short(@NotNull byte[] byteNumber) { 105 | short result = 0; 106 | for (int i = 0; i < 2; i++) { 107 | result <<= 8; // 意思就是 l = l << 8 108 | result |= (byteNumber[i] & 0xff); // l = l | (b[i]&0xff) 109 | } 110 | return result; 111 | } 112 | 113 | /** 114 | * byte数组转int 115 | * 10进制 116 | * 117 | * @param byteArr byte 数组 118 | * @return int类型 119 | * {@link #byteArr2Int2(byte[])} 这是另一种写法,其实效果是一样的 120 | */ 121 | public static int byteArr2Int(@NotNull byte[] byteArr) { 122 | return (byteArr[0] & 0xff) << 24 123 | | (byteArr[1] & 0xff) << 16 124 | | (byteArr[2] & 0xff) << 8 125 | | (byteArr[3] & 0xff); 126 | } 127 | 128 | 129 | /** 130 | * byte数组转成int 131 | * 132 | * @param byteArr byte 数组 133 | * @return int类型 134 | * {@link #byteArr2Int(byte[])} 这是另一种写法,其实效果是一样的 135 | */ 136 | public static int byteArr2Int2(@NotNull byte[] byteArr) { 137 | // 另一种写法,其实效果是一样的 138 | int num = byteArr[3] & 0xFF; 139 | num |= ((byteArr[2] << 8) & 0xFF00); 140 | num |= ((byteArr[1] << 16) & 0xFF00); 141 | num |= ((byteArr[0] << 24) & 0xFF00); 142 | return num; 143 | } 144 | 145 | /** 146 | * byte[] 转 char 147 | * 148 | * @param byteArr byte数组 149 | * @return char字符 150 | */ 151 | public static char byteArr2Char(@NotNull byte[] byteArr) { 152 | char c = (char) (((byteArr[0] & 0xFF) << 8) | (byteArr[1] & 0xFF)); 153 | return c; 154 | } 155 | 156 | 157 | /** 158 | * byte[] 转 char[] (10进制) 159 | * 160 | * @param byteArr byte数组 161 | * @return char数组 162 | */ 163 | public static char[] byteArr2CharArr(@NotNull byte[] byteArr) { 164 | Charset cs = Charset.forName("UTF-8"); 165 | ByteBuffer bb = ByteBuffer.allocate(byteArr.length); 166 | bb.put(byteArr); 167 | bb.flip(); 168 | CharBuffer cb = cs.decode(bb); 169 | return cb.array(); 170 | } 171 | 172 | 173 | /** 174 | * byte数组 转成 16进制char数组(默认转换成小写形式) 175 | * 176 | * @param byteArr byte数组 177 | * @return 16进制char数组 178 | */ 179 | public static char[] byteArr2CharArrHex(@NotNull byte[] byteArr) { 180 | return byteArr2CharArrHex(byteArr, true); 181 | } 182 | 183 | /** 184 | * byte数组 转成 16进制char数组 185 | * 186 | * @param byteArr byte数组 187 | * @param toLowerCase true:转换成小写格式 ,false:转换成大写格式 188 | * @return 16进制char数组 189 | */ 190 | public static char[] byteArr2CharArrHex(@NotNull byte[] byteArr, @NotNull boolean toLowerCase) { 191 | return byteArr2CharArrHex(byteArr, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); 192 | } 193 | 194 | /** 195 | * byte数组 转成 16进制char数组(默认转换成小写形式) 196 | * 197 | * @param byteArr byte数组 198 | * @param toDigits 用于控制输出的char[] 199 | * @return 16进制char数组 200 | */ 201 | private static char[] byteArr2CharArrHex(@NotNull byte[] byteArr, @NotNull char[] toDigits) { 202 | int index = 0; 203 | char[] hexChar = new char[byteArr.length * 2];//相当于: char[] out = new char[len << 1]; 204 | for (int i = 0; i < byteArr.length; i++) { 205 | hexChar[index++] = toDigits[byteArr[i] >> 4 & 0xF]; 206 | hexChar[index++] = toDigits[byteArr[i] & 0xF]; 207 | // 无符号位移 208 | hexChar[index++] = toDigits[(0xF0 & byteArr[i]) >>> 4]; 209 | // 有符号的位移 210 | // hexChar[j++] = toDigits[byteArr[i] >> 4 & 0xF]; 211 | hexChar[index++] = toDigits[0x0F & byteArr[i]]; 212 | } 213 | return hexChar; 214 | } 215 | 216 | 217 | /** 218 | * byte 数组 转换成String字符串 219 | * 10进制 220 | * 221 | * @param byteArr byte 数组 222 | * @return String字符串 223 | */ 224 | public static String byteArr2String(@NotNull byte[] byteArr) { 225 | try { 226 | return new String(byteArr, StandardCharsets.UTF_8); 227 | } catch (Exception e) { 228 | e.printStackTrace(); 229 | } 230 | return null; 231 | } 232 | 233 | 234 | /** 235 | * byte 数组 转换成 16进制的String字符串 236 | * 237 | * @param byteArr byte 数组 238 | * @return 16进制的String字符串 239 | * @deprecated 该方法在某些情况会有bug, 请使用{@link #byteArr2StringHex2(byte[])} 替代。 240 | */ 241 | @Deprecated 242 | public static String byteArr2StringHex(@NotNull byte[] byteArr) { 243 | StringBuilder stringBuilder = new StringBuilder(""); 244 | if (byteArr == null || byteArr.length <= 0) { 245 | return null; 246 | } 247 | for (int i = 0; i < byteArr.length; i++) { 248 | int v = byteArr[i] & 0xFF; 249 | String hv = Integer.toHexString(v); 250 | if (hv.length() < 2) { 251 | stringBuilder.append(0); 252 | } 253 | stringBuilder.append(hv); 254 | } 255 | return stringBuilder.toString(); 256 | } 257 | 258 | 259 | /** 260 | * 将字节数组转换为十六进制字符串(默认转换成小写形式) 261 | * 262 | * @param byteArr byte 数组 263 | * @return 16进制的String字符串 264 | */ 265 | public static String byteArr2StringHex2(@NotNull byte[] byteArr) { 266 | return byteArr2StringHex2(byteArr, true); 267 | } 268 | 269 | 270 | /** 271 | * 将字节数组转换为十六进制字符串 272 | * 273 | * @param data byte[] 274 | * @param toLowerCase 是否转换成小写形式 true 转换成小写格式 , false 转换成大写格式 275 | * @return 十六进制String 276 | */ 277 | public static String byteArr2StringHex2(@NotNull byte[] data, @NotNull boolean toLowerCase) { 278 | return byteArr2StringHex2(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); 279 | } 280 | 281 | /** 282 | * 将字节数组转换为十六进制字符串 283 | * 284 | * @param data byte[] 285 | * @param toDigits 用于控制输出的char[] 286 | * @return 十六进制String 287 | */ 288 | private static String byteArr2StringHex2(@NotNull byte[] data, @NotNull char[] toDigits) { 289 | return charArr2StringHex(byteArr2CharArrHex(data, toDigits)); 290 | } 291 | 292 | 293 | //////////////////////////////////////////////////////////////////////////////// 294 | /// 295 | /// short 和 short 数组转换成其它类型 296 | /// short 取值范围:-32768(-2^15)到 32767(2^15 - 1) 297 | //////////////////////////////////////////////////////////////////////////////// 298 | 299 | 300 | /** 301 | * short类型转byte数组 302 | * 303 | * @param shortNumber 304 | * @return 305 | */ 306 | public static byte[] short2Byte(@NotNull short shortNumber) { 307 | byte[] b = new byte[2]; 308 | for (int i = 0; 309 | i < 2; 310 | i++) { 311 | int offset = 16 - (i + 1) * 8; //因为byte占4个字节,所以要计算偏移量 312 | b[i] = (byte) ((shortNumber >> offset) & 0xff); //把16位分为2个8位进行分别存储 313 | } 314 | return b; 315 | } 316 | 317 | public static int short2Int(@NotNull short shortNumber) { 318 | return Integer.parseInt(short2String(shortNumber)); 319 | } 320 | 321 | public static long short2Long(@NotNull short shortNumber) { 322 | return Long.parseLong(short2String(shortNumber)); 323 | } 324 | 325 | public static float short2Float(@NotNull short shortNumber) { 326 | return Float.parseFloat(short2String(shortNumber)); 327 | } 328 | 329 | public static double short2Double(@NotNull short shortNumber) { 330 | return Double.parseDouble(short2String(shortNumber)); 331 | } 332 | 333 | public static String short2String(@NotNull short shortNumber) { 334 | return String.valueOf(shortNumber); 335 | } 336 | 337 | 338 | //////////////////////////////////////////////////////////////////////////////// 339 | /// 340 | /// int 和 int 数组转换成其它类型 341 | /// int 取值范围:-2,147,483,648(-2^31) 到 2,147,483,647(2^31 - 1) 342 | //////////////////////////////////////////////////////////////////////////////// 343 | 344 | public static byte int2Byte(@NotNull int intNumber) { 345 | // 强转会损失精度 346 | return (byte) intNumber; 347 | } 348 | 349 | 350 | /** 351 | * int类型 转换成 String类型 352 | * 此方法过时,请使用 {@link #int2String2(int)} 或者 {@link #int2String3(int)} 这个方法替代 353 | * 358 | * 359 | * @param intNumber int类型 360 | * @return String类型 361 | */ 362 | @Deprecated 363 | public static String int2String(@NotNull int intNumber) { 364 | return intNumber + ""; 365 | } 366 | 367 | /** 368 | * int类型 转换成 String类型 369 | *

也可以把 十六进制数字的基本数据类型 转成 String,例如:int2String2(0xFF);

370 | *

371 | *

376 | * 380 | *

381 | * 382 | * @param intNumber int类型 383 | * @return String类型 384 | */ 385 | public static String int2String2(@NotNull int intNumber) { 386 | return Integer.toString(intNumber); 387 | } 388 | 389 | 390 | /** 391 | * 10进制 转 2进制 392 | * 393 | * @param data 10进制 int类型 394 | * @return 16进制 字符串 395 | */ 396 | public static String intDecimal2StringBinary(@NotNull int data) { 397 | return Integer.toBinaryString(data); 398 | } 399 | 400 | /** 401 | * 10进制 转 8进制 402 | * 403 | * @param data 10进制 int类型 404 | * @return 16进制 字符串 405 | */ 406 | public static String intDecimal2StringOctal(@NotNull int data) { 407 | return Integer.toOctalString(data); 408 | } 409 | 410 | /** 411 | * 10进制 转 16进制 412 | * 413 | * @param data 10进制 int类型 414 | * @return 16进制 字符串 415 | */ 416 | public static String intDecimal2StringHex(@NotNull int data) { 417 | return Integer.toHexString(data); 418 | } 419 | 420 | 421 | 422 | /** 423 | * int类型 转换成 String类型 424 | * 429 | * 430 | * @param intNumber int类型 431 | * @return String类型 432 | */ 433 | public static String int2String3(@NotNull int intNumber) { 434 | return String.valueOf(intNumber); 435 | } 436 | 437 | /** 438 | * int转byte数组 439 | * 440 | * @param intNumber int类型 441 | * @return byte数组 442 | *

{@link #int2ByteArr2(int)} 这是另一种写法,其实效果是一样的

443 | */ 444 | public static byte[] int2ByteArr(@NotNull int intNumber) { 445 | // int是4个字节 所以要4个byte 446 | byte[] b = new byte[4]; 447 | b[0] = (byte) (intNumber & 0xff); 448 | b[1] = (byte) ((intNumber >> 8) & 0xff); 449 | b[2] = (byte) ((intNumber >> 16) & 0xff); 450 | b[3] = (byte) ((intNumber >> 24) & 0xff); 451 | return b; 452 | } 453 | 454 | /** 455 | * int转byte数组 456 | * 457 | * @param intNumber int类型 458 | * @return byte数组 459 | * {@link #int2ByteArr(int)} 这是另一种写法,其实效果是一样的 460 | */ 461 | public static byte[] int2ByteArr2(@NotNull int intNumber) { 462 | // 另一种写法 效果是一样的 463 | byte[] b = new byte[4]; 464 | b[0] = (byte) ((intNumber >> 24) & 0xFF); 465 | b[1] = (byte) ((intNumber >> 16) & 0xFF); 466 | b[2] = (byte) ((intNumber >> 8) & 0xFF); 467 | b[3] = (byte) (intNumber & 0xFF); 468 | return b; 469 | } 470 | 471 | 472 | ////////////////////////////////////////////////////////////////////////////////////////////// 473 | /// 474 | /// long 和 long 数组转换成其它类型 475 | /// long 取值范围:-9,223,372,036,854,775,808(-2^63) 到 9,223,372,036,854,775,807(2^63 -1) 476 | ////////////////////////////////////////////////////////////////////////////////////////////// 477 | 478 | 479 | public static byte long2Byte(@NotNull long longNumber) { 480 | return string2Byte(long2String(longNumber)); 481 | } 482 | 483 | public static short long2Short(@NotNull long longNumber) { 484 | return string2Short(long2String(longNumber)); 485 | } 486 | 487 | public static int long2Int(@NotNull long longNumber) { 488 | return Integer.parseInt(long2String(longNumber)); 489 | } 490 | 491 | public static float long2Float(@NotNull long longNumber) { 492 | return string2Float(long2String(longNumber)); 493 | } 494 | 495 | public static double long2Double(@NotNull long longNumber) { 496 | return Double.parseDouble(long2String(longNumber)); 497 | } 498 | 499 | public static String long2String(@NotNull long longNumber) { 500 | return String.valueOf(longNumber); 501 | } 502 | 503 | 504 | //////////////////////////////////////////////////////////////////////////////// 505 | /// 506 | /// float 和 float 数组转换成其它类型 507 | /// 单精度、32位 508 | //////////////////////////////////////////////////////////////////////////////// 509 | 510 | 511 | public static byte float2Byte(@NotNull float floatNumber) { 512 | return 0; 513 | } 514 | 515 | public static int float2Short(@NotNull float floatNumber) { 516 | return 0; 517 | } 518 | 519 | public static long float2Int(@NotNull float floatNumber) { 520 | return 0; 521 | } 522 | 523 | public static long float2Long(@NotNull float floatNumber) { 524 | return Long.parseLong(float2String(floatNumber)); 525 | } 526 | 527 | public static double float2Double(@NotNull float floatNumber) { 528 | return Double.parseDouble(float2String(floatNumber)); 529 | } 530 | 531 | public static String float2String(@NotNull float floatNumber) { 532 | return String.valueOf(floatNumber); 533 | } 534 | 535 | 536 | //////////////////////////////////////////////////////////////////////////////// 537 | /// 538 | /// double 和 double 数组转换成其它类型 539 | /// 双精度、64位 540 | //////////////////////////////////////////////////////////////////////////////// 541 | 542 | 543 | public static byte double2Byte(@NotNull short doubleNumber) { 544 | return 0; 545 | } 546 | 547 | public static int double2Short(@NotNull short doubleNumber) { 548 | return 0; 549 | } 550 | 551 | public static long double2Int(@NotNull short doubleNumber) { 552 | return 0; 553 | } 554 | 555 | public static long double2Long(@NotNull short doubleNumber) { 556 | return Long.parseLong(double2String(doubleNumber)); 557 | } 558 | 559 | public static float double2Float(@NotNull short doubleNumber) { 560 | return 0; 561 | } 562 | 563 | public static String double2String(@NotNull short doubleNumber) { 564 | return String.valueOf(doubleNumber); 565 | } 566 | 567 | 568 | //////////////////////////////////////////////////////////////////////////////// 569 | /// 570 | /// String 和 String 数组转换成其它类型 571 | /// 572 | //////////////////////////////////////////////////////////////////////////////// 573 | 574 | /** 575 | * String 转成 byte 576 | * [tips]: 1. 577 | * 578 | * @param data 579 | * @return 580 | */ 581 | public static byte string2Byte(@NotNull String data) { 582 | return string2Byte(data, 10); 583 | } 584 | 585 | /** 586 | * String 转成 byte 587 | * [tips]: 1.不能超过byte取值范围 588 | * byte取值范围(10进制)是:-128 到 127 589 | * 换算成2进制是:-10000000 到 1111111 590 | * 换算成16进制是:-80 到 7f 591 | * 592 | * @param data 593 | * @param radix 进制 比如2、10、16 默认为10进制 594 | * @return 595 | */ 596 | public static byte string2Byte(@NotNull String data, @NotNull int radix) { 597 | return Byte.parseByte(data, radix); 598 | } 599 | 600 | /** 601 | * String 转成 byte 602 | * 将字符串解码为字节。 603 | * 接受十进制、十六进制和八进制数: 604 | * 十六进制:0x 0X 605 | * 八进制:0 606 | * 十进制:- + 607 | * 608 | * @param data 609 | * @return 610 | */ 611 | public static byte string2Byte2(@NotNull String data) { 612 | return Byte.decode(data); 613 | } 614 | 615 | public static short string2Short(@NotNull String data) { 616 | return Short.parseShort(data); 617 | } 618 | 619 | /** 620 | * String转int类型 621 | * 【注意】: 中文、英文、中英文混合、标点符号、甚至超过byte范围都会报错。 622 | * unicode码也不行 ,例如:u+4E00、u+4E00、4E00 623 | * 624 | * @param data 625 | * @return 转成无符号的 int 类型 626 | *

{@link #string2Int(String, boolean)}

627 | *

{@link #string2IntBinary(String, boolean)}

628 | *

{@link #string2IntOctal(String, boolean)}

629 | *

{@link #string2IntHexadecimal(String, boolean)}

630 | *

{@link #string2Int2(String)}

631 | */ 632 | public static int string2Int(@NotNull String data) { 633 | return string2Int(data, false); 634 | } 635 | 636 | 637 | /** 638 | * String转int类型 639 | * 【注意】: 中文、英文、中英文混合、标点符号、甚至超过byte范围都会报错。 640 | * unicode码也不行 ,例如:u+4E00、u+4E00、4E00 641 | * 642 | * @param data 643 | * @param isUnsignedInt 是否要转成无符号的int类型 644 | * @return int 645 | *

{@link #string2Int(String)}

646 | *

{@link #string2IntBinary(String, boolean)}

647 | *

{@link #string2IntOctal(String, boolean)}

648 | *

{@link #string2IntHexadecimal(String, boolean)}

649 | *

{@link #string2Int2(String)}

650 | */ 651 | public static int string2Int(@NotNull String data, @NotNull boolean isUnsignedInt) { 652 | return string2Int(data, isUnsignedInt, 10); 653 | } 654 | 655 | /** 656 | * String转int类型(2进制) 657 | * 658 | * @param data 659 | * @param isUnsignedInt 660 | * @return String字符串 661 | * {@link #string2Int(String)} 662 | *

{@link #string2Int(String, boolean)}

663 | *

{@link #string2IntOctal(String, boolean)}

664 | *

{@link #string2IntHexadecimal(String, boolean)}

665 | *

{@link #string2Int2(String)}

666 | */ 667 | public static int string2IntBinary(@NotNull String data, @NotNull boolean isUnsignedInt) { 668 | return string2Int(data, isUnsignedInt, 2); 669 | } 670 | 671 | /** 672 | * String转int类型(8进制) 673 | * 674 | * @param data 675 | * @param isUnsignedInt 676 | * @return String字符串 677 | *

{@link #string2Int(String)}

678 | *

{@link #string2Int(String, boolean)}

679 | *

{@link #string2IntBinary(String, boolean)}

680 | *

{@link #string2IntHexadecimal(String, boolean)}

681 | *

{@link #string2Int2(String)}

682 | */ 683 | public static int string2IntOctal(@NotNull String data, @NotNull boolean isUnsignedInt) { 684 | return string2Int(data, isUnsignedInt, 8); 685 | } 686 | 687 | /** 688 | * String转int类型(16进制) 689 | * 690 | * @param data 691 | * @param isUnsignedInt 692 | * @return int类型 693 | *

{@link #string2Int(String)}

694 | *

{@link #string2Int(String, boolean)}

695 | *

{@link #string2IntBinary(String, boolean)}

696 | *

{@link #string2IntOctal(String, boolean)}

697 | *

{@link #string2Int2(String)}

698 | */ 699 | public static int string2IntHexadecimal(@NotNull String data, @NotNull boolean isUnsignedInt) { 700 | return string2Int(data, isUnsignedInt, 16); 701 | } 702 | 703 | /** 704 | * String转int类型 705 | * 706 | * @param data 707 | * @param isUnsignedInt 708 | * @param radix 进制 比如2(Binary)、8(Octal)、10(Decimal)、16(Hexadecimal) ,默认为10进制 709 | * @return int 710 | *

{@link #string2Int(String)}

711 | *

{@link #string2Int(String, boolean)}

712 | *

{@link #string2IntBinary(String, boolean)}

713 | *

{@link #string2IntOctal(String, boolean)}

714 | *

{@link #string2IntHexadecimal(String, boolean)}

715 | *

{@link #string2Int2(String)}

716 | */ 717 | private static int string2Int(@NotNull String data, @NotNull boolean isUnsignedInt, @NotNull int radix) { 718 | if (isUnsignedInt == false) { 719 | return Integer.parseInt(data, radix); 720 | } else { 721 | return Integer.parseUnsignedInt(data, radix); 722 | } 723 | } 724 | 725 | 726 | /** 727 | * String转int类型 728 | * 729 | * @param data String类型 730 | * @return int类型 731 | *

{@link #string2Int(String)}

732 | *

{@link #string2Int(String, boolean)}

733 | *

{@link #string2IntBinary(String, boolean)}

734 | *

{@link #string2IntOctal(String, boolean)}

735 | *

{@link #string2IntHexadecimal(String, boolean)}

736 | */ 737 | public static int string2Int2(@NotNull String data) { 738 | return Integer.valueOf(data).intValue(); 739 | } 740 | 741 | 742 | /** 743 | * String转long类型 744 | * 745 | * @param data 746 | * @return 转成无符号的 long 类型 747 | */ 748 | public static long string2Long(@NotNull String data) { 749 | return Long.parseLong(data); 750 | } 751 | 752 | /** 753 | * String转 long 类型 754 | * 755 | * @param data 756 | * @param isUnsignedLong 是否要转成无符号的 long 类型 757 | * @return 转成的 long 类型 758 | */ 759 | public static long string2Long(@NotNull String data, @NotNull boolean isUnsignedLong) { 760 | if (isUnsignedLong == false) { 761 | return Long.parseLong(data); 762 | } else { 763 | return Long.parseUnsignedLong(data); 764 | } 765 | } 766 | 767 | public static float string2Float(@NotNull String data) { 768 | return Float.parseFloat(data); 769 | } 770 | 771 | public static double string2Double(@NotNull String data) { 772 | return Double.parseDouble(data); 773 | } 774 | 775 | public static boolean string2Boolean(@NotNull String data) { 776 | return Boolean.parseBoolean(data); 777 | } 778 | 779 | ////////////////////////////////////////////////// 780 | 781 | 782 | //十六进制转十进制,例如:0xFFFF 783 | 784 | // Integer.valueOf("FFFF",16).toString();  //valueOf()方法返回Integer类型,调用toString()返回字符串 785 | // Integer.parseInt("FFFF",16);  //返回int基本数据类型 786 | // Integer.toString(0xFFFF);  //该方法可直接传入表示十六进制数字的基本数据类型,方法返回字符串 787 | // 788 | // //八进制转十进制,例如:017 789 | // Integer.valueOf("17",8).toString();  //valueOf()方法返回Integer类型,调用toString()返回字符串 790 | // Integer.parseInt("17",8);  //返回int基本数据类型 791 | // Integer.toString(017);  //该方法可直接传入表示八进制数字的基本数据类型,方法返回字符串 792 | // 793 | // //二进制转十进制,例如:0101 794 | // Integer.valueOf("0101",2).toString();  //valueOf()方法返回Integer类型,调用toString()返回字符串 795 | // Integer.parseInt("0101",2);  //返回int基本数据类型 796 | 797 | // 2(Binary)、8(Octal)、10(Decimal)、16(Hexadecimal) 798 | 799 | //十进制转其他进制 800 | 801 | //Integer.toHexString(10);  //将10转换为十六进制,返回字符串类型 802 | // 803 | // Integer.toOctalString(10);  //将10转为八进制,返回字符串类型 804 | // 805 | // Integer.toBinaryString(10);  //将10转为二进制,返回字符串类型 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | /** 814 | * 16进制 转 10进制 815 | * 816 | *

示例:stringHex2StringDecimal("FFFF");

817 | * 818 | * 822 | * 823 | * @param data 10进制 字符串 824 | * @return 16进制 字符串 825 | */ 826 | public static String stringHex2StringDecimal(@NotNull String data) { 827 | return Integer.valueOf(data, 16).toString(); 828 | } 829 | 830 | /** 831 | * 16进制 转 10进制 832 | * 示例:stringHex2IntDecimal("FFFF"); 833 | * 834 | * @param data 10进制 字符串 835 | * @return 16进制 int类型 836 | * 另外两种16进制转10进制的方式请查看: 837 | *

{@link #stringHex2StringDecimal(String)}

838 | *

{@link #stringHex2IntDecimal(String)}

839 | *

{@link #int2String2(int)}

840 | */ 841 | public static int stringHex2IntDecimal(@NotNull String data) { 842 | return Integer.parseInt(data, 16); 843 | } 844 | 845 | 846 | 847 | 848 | 849 | /** 850 | * 8进制 转 10进制 851 | * 852 | *

示例:stringOctal2StringDecimal("121");

853 | * 854 | * @param data 8进制 字符串 855 | * @return 10进制 字符串 856 | */ 857 | public static String stringOctal2StringDecimal(@NotNull String data) { 858 | return Integer.valueOf(data, 8).toString(); 859 | } 860 | 861 | /** 862 | * 8进制 转 10进制 863 | * 示例:stringOctal2IntDecimal("121"); 864 | * 865 | * @param data 8进制 字符串 866 | * @return 10进制 int类型 867 | */ 868 | public static int stringOctal2IntDecimal(@NotNull String data) { 869 | return Integer.parseInt(data, 8); 870 | } 871 | 872 | 873 | /** 874 | * 2进制 转 10进制 875 | * 876 | * @param data 10进制 字符串 877 | * @return 16进制 字符串 878 | */ 879 | public static String stringBinary2StringDecimal(@NotNull String data) { 880 | return Integer.valueOf(data, 2).toString(); 881 | } 882 | 883 | /** 884 | * 2进制 转 10进制 885 | * 886 | * @param data 10进制 字符串 887 | * @return 16进制 int类型 888 | */ 889 | public static int stringBinary2IntDecimal(@NotNull String data) { 890 | return Integer.parseInt(data,2); 891 | } 892 | 893 | 894 | /////////////////////////////////////////////////// 895 | 896 | /** 897 | * String字符串转成 byte 数组 898 | * 默认为utf-8编码格式 899 | * 900 | * @param data String字符串 901 | * @return byte 数组 902 | * 例如:DataUtil.stringHex2ByteArr("好"); 903 | */ 904 | public static byte[] string2ByteArr(@NotNull String data) { 905 | try { 906 | return string2ByteArr(data, null); 907 | } catch (Exception e) { 908 | e.printStackTrace(); 909 | } 910 | return null; 911 | } 912 | 913 | /** 914 | * String字符串转成 byte 数组 915 | * 916 | * @param data String字符串 917 | * @param charsetNametypes 编码格式 默认为utf-8 918 | * @return byte 数组 919 | * 例如:DataUtil.string2ByteArrWithCharset("好","utf-16"); 920 | */ 921 | public static byte[] string2ByteArr(@NotNull String data, @NotNull String charsetNametypes) throws Exception { 922 | if (charsetNametypes == null || charsetNametypes.equals("")) { 923 | return data.getBytes("utf-8"); 924 | } else { 925 | if (charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_UTF8) || 926 | charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_UTF16) 927 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_UTF32) 928 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_UNICODE) 929 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_GBK) 930 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_GB2312) 931 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_GB18030) 932 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_ASCII) 933 | || charsetNametypes.equals(CharsetNameTypes.CHARSETNAME_ISO_8859_1)) { 934 | return data.getBytes(charsetNametypes); 935 | } else { 936 | throw new IllegalAccessException("编码格式不正确,请检查编码格式"); 937 | } 938 | } 939 | } 940 | 941 | 942 | /** 943 | * 16进制的String字符串 转换成 byte 数组 944 | * 945 | * @param data 16进制的String字符串 946 | * @return byte 数组 947 | * 例如:DataUtil.stringHex2ByteArr("e4bda0e5a5bd"); 948 | */ 949 | public static byte[] stringHex2ByteArr(@NotNull String data) { 950 | try { 951 | if(isHexadecimal(data)!=true){ 952 | throw new IllegalAccessException("该方法不支持传入的此类型字符串,请使用 string2ByteArr(String)方法替代"); 953 | } 954 | int len = data.length(); 955 | byte[] d = new byte[len / 2]; 956 | for (int i = 0; i < len; i += 2) { 957 | // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个进制字节 958 | d[i / 2] = (byte) ((Character.digit(data.charAt(i), 16) << 4) + Character 959 | .digit(data.charAt(i + 1), 16)); 960 | } 961 | return d; 962 | } catch (Exception e) { 963 | e.printStackTrace(); 964 | } 965 | return null; 966 | } 967 | 968 | //////////////////////////////////////////////////////////////////////////////// 969 | /// 970 | /// char 和 char 数组 数组转换成其它类型 971 | /// 972 | //////////////////////////////////////////////////////////////////////////////// 973 | 974 | 975 | public static String char2String(@NotNull char charNumber) { 976 | return String.valueOf(charNumber); 977 | } 978 | 979 | /** 980 | * char 转换成 byte[] 数组 981 | * 982 | * @param charNumber 983 | * @return 984 | */ 985 | public static byte[] char2ByteArr(@NotNull char charNumber) { 986 | byte[] b = new byte[2]; 987 | b[0] = (byte) ((charNumber & 0xFF00) >> 8); 988 | b[1] = (byte) (charNumber & 0xFF); 989 | return b; 990 | } 991 | 992 | /** 993 | * 将十六进制字符转换成一个整数 994 | * 995 | * @param ch 十六进制char 996 | * @param index 十六进制字符在字符数组中的位置 997 | * @return 一个整数 998 | * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常 999 | */ 1000 | public static int charHex2Int(@NotNull char ch, @NotNull int index) { 1001 | int digit = Character.digit(ch, 16); 1002 | if (digit == -1) { 1003 | throw new RuntimeException("Illegal hexadecimal character " + ch 1004 | + " at index " + index); 1005 | } 1006 | return digit; 1007 | } 1008 | 1009 | 1010 | /** 1011 | * char[] 转成 byte[] (10进制) 1012 | * 1013 | * @param charArr char数组 1014 | * @return byte数组 1015 | */ 1016 | public static byte[] charArr2ByteArr(@NotNull char[] charArr) { 1017 | Charset cs = Charset.forName("UTF-8"); 1018 | CharBuffer cb = CharBuffer.allocate(charArr.length); 1019 | cb.put(charArr); 1020 | cb.flip(); 1021 | ByteBuffer bb = cs.encode(cb); 1022 | return bb.array(); 1023 | } 1024 | 1025 | /** 1026 | * 将十六进制字符数组转换为字节数组 1027 | * 1028 | * @param charArr 十六进制char[] 1029 | * @return byte[] 字节数组 1030 | * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常 1031 | */ 1032 | public static byte[] charArrHex2ByteArr(@NotNull char[] charArr) { 1033 | int len = charArr.length; 1034 | if ((len & 0x01) != 0) { 1035 | throw new RuntimeException("Odd number of characters."); 1036 | } 1037 | byte[] out = new byte[len >> 1]; 1038 | for (int i = 0, j = 0; j < len; i++) { 1039 | int f = charHex2Int(charArr[j], j) << 4; 1040 | j++; 1041 | f = f | charHex2Int(charArr[j], j); 1042 | j++; 1043 | out[i] = (byte) (f & 0xFF); 1044 | } 1045 | return out; 1046 | } 1047 | 1048 | /** 1049 | * 将char数组转换成十六进制字符串 1050 | * 1051 | * @return 1052 | */ 1053 | public static String charArr2StringHex(@NotNull char[] charArr) { 1054 | return new String(charArr); 1055 | } 1056 | 1057 | //////////////////////////////////////////////////////////////////////////////// 1058 | /// 1059 | /// 判断是否是2进制、8进制、16进制 1060 | /// 2(Binary)、8(Octal)、10(Decimal)、16(Hexadecimal) 1061 | /// 2进制:0和1 1062 | /// 8进制:0开头,例如:0123 (8进制没有8和9) 1063 | /// 16进制:0x开头,例如:0x23 1064 | //////////////////////////////////////////////////////////////////////////////// 1065 | 1066 | 1067 | /** 1068 | * 判断是否是2进制 1069 | * 1070 | * @param data 1071 | * @return 1072 | */ 1073 | public static boolean isBinary(String data) { 1074 | String regex = "[0-1]+$"; 1075 | if (data.matches(regex)) { 1076 | System.out.println(data.toUpperCase() + "是2进制数"); 1077 | return true; 1078 | } else { 1079 | System.out.println(data.toUpperCase() + "不是2进制数"); 1080 | return false; 1081 | } 1082 | } 1083 | 1084 | /** 1085 | * 判断是否是8进制 1086 | * 1087 | * @param data 1088 | * @return 1089 | */ 1090 | public static boolean isOctal(String data) { 1091 | String substring; 1092 | String regex = "[0-7]+$"; 1093 | if (data.startsWith("0")) { 1094 | substring = data.substring(1); 1095 | if (substring.matches(regex)) { 1096 | System.out.println(data + "是8进制数"); 1097 | return true; 1098 | } else { 1099 | System.out.println(data + "不是8进制数"); 1100 | return false; 1101 | } 1102 | } else { 1103 | return false; 1104 | } 1105 | } 1106 | 1107 | /** 1108 | * 判断是否是10进制 1109 | * 1110 | * @param data 1111 | * @return 1112 | */ 1113 | public static boolean isDecimal(String data) { 1114 | if (data.startsWith("0") || data.startsWith("0x") || data.startsWith("0X")) { 1115 | System.out.println(data + "不是10进制数"); 1116 | return false; 1117 | } 1118 | String regex = "[0-9]+$"; 1119 | if (data.matches(regex)) { 1120 | System.out.println(data + "是10进制数"); 1121 | return true; 1122 | } else { 1123 | System.out.println(data + "不是10进制数"); 1124 | return false; 1125 | } 1126 | } 1127 | 1128 | 1129 | /** 1130 | * 判断是否是16进制 1131 | * 1132 | * @param data 1133 | * @return 1134 | */ 1135 | public static boolean isHexadecimal(String data) { 1136 | String regex = "^[A-Fa-f0-9]+$"; 1137 | if (data.matches(regex)) { 1138 | System.out.println(data + "是16进制数"); 1139 | return true; 1140 | } else { 1141 | System.out.println(data + "不是16进制数"); 1142 | return false; 1143 | } 1144 | } 1145 | } 1146 | -------------------------------------------------------------------------------- /codes/data_util/com/lzw/data.util/Test.java: -------------------------------------------------------------------------------- 1 | package com.lzw.data.util; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.CharBuffer; 5 | import java.nio.charset.Charset; 6 | 7 | /** 8 | * @desp 测试类 9 | * @author LZW 10 | * @version 1.0 11 | * @date 2019-05-01 12 | * @website https://github.com/AweiLoveAndroid/CommonDevKnowledge 13 | * @mail lzw20099002@126.com 有任何疑问欢迎发邮件 或者 加微信咨询(本开源库README.md有介绍) 14 | * 15 | */ 16 | public class Test { 17 | 18 | public static void main(String[] args) { 19 | // String[] strArr = {"你", "好", "你好", "hell5", "你好hell5"}; 20 | // String[] charsetArr = {"", "utf-8", "utf-16", "utf-32", "unicode", "gbk", "gb2312", "GB18030", "ascii", "ISO-8859-1"}; 21 | // for (String str : strArr) { 22 | // System.out.println(str); 23 | // for (String charset : charsetArr) { 24 | // test(str, charset); 25 | // } 26 | // System.out.println("============================"); 27 | // } 28 | 29 | 30 | System.out.println(DataUtil.stringHex2StringDecimal("FFFF")); // 65535 31 | 32 | String data = "0x123"; 33 | System.out.println(isDecimal(data)); 34 | } 35 | 36 | public static void test(String data, String charsetName) { 37 | try { 38 | byte[] byteArrays = DataUtil.string2ByteArr(data, charsetName); 39 | String result = DataUtil.byteArr2StringHex2(byteArrays); 40 | if (charsetName.equals("")) { 41 | System.out.println("默认编码:" + charsetName 42 | + " 系统默认编码:" + System.getProperty("file.encoding") 43 | + " 系统默认字符编码:" + Charset.defaultCharset() 44 | + " 操作系统用户使用的语言:" + System.getProperty("user.language") 45 | + " 所占字节数:" + byteArrays.length 46 | + " 16进制:" + result); 47 | } else { 48 | System.out.println("编码:" + charsetName 49 | + " 系统默认编码:" + System.getProperty("file.encoding") 50 | + " 系统默认字符编码:" + Charset.defaultCharset() 51 | + " 操作系统用户使用的语言:" + System.getProperty("user.language") 52 | + " 所占字节数:" + byteArrays.length 53 | + " 16进制:" + result); 54 | } 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | public static boolean isOctal(String data) { 61 | String substring; 62 | String regex = "[0-7]+$"; 63 | if (data.startsWith("0")) { 64 | substring = data.substring(1); 65 | if (substring.matches(regex)) { 66 | System.out.println(data.toUpperCase() + "是8进制数"); 67 | return true; 68 | } else { 69 | System.out.println(data.toUpperCase() + "不是8进制数"); 70 | return false; 71 | } 72 | } else { 73 | return false; 74 | } 75 | } 76 | 77 | public static boolean isDecimal(String data) { 78 | String regex = "[0-9]+$"; 79 | if (data.matches(regex)) { 80 | System.out.println(data.toUpperCase() + "是10进制数"); 81 | return true; 82 | } else { 83 | System.out.println(data.toUpperCase() + "不是10进制数"); 84 | return false; 85 | } 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /design_patterns/README.md: -------------------------------------------------------------------------------- 1 | 由光头强引发的Java23种设计模式的思考: 2 | 3 | 代码|详细文章讲解 4 | ----|---- 5 | [](src/com/lzw/part1_creation_mode/builder)| [Java设计模式4之建造者模式(光头强买电锯引发的思考)](https://www.jianshu.com/p/713120e9dc59) -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/README.md: -------------------------------------------------------------------------------- 1 | 结构型模式分为以下 5 种(有的版也把简单工厂模式算在里面,就是6种): 2 | 3 | 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。 4 | 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。 5 | 工厂方法(FactoryMethod)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。 6 | 抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。 7 | 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。 -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw/ChainsawBuilder.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw; 2 | 3 | /** 4 | * 链锯建筑者 5 | */ 6 | public interface ChainsawBuilder { 7 | 8 | // 蓄电池 9 | void battery(); 10 | // 电动机 11 | void motor(); 12 | // 减速箱 13 | void reductionGearbox(); 14 | // 防护罩 15 | void hood(); 16 | // 手柄 17 | void handle(); 18 | // 开关 19 | void switches(); 20 | // 插头 21 | void plug(); 22 | // 圆锯片 23 | void circularSaw(); 24 | 25 | // 获取链锯(产品)的实例 26 | Chainsaws getChainsaws(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw/ChainsawBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw; 2 | 3 | /** 4 | * 链锯建筑者(具体建筑者) 5 | */ 6 | public class ChainsawBuilderImpl implements ChainsawBuilder{ 7 | 8 | private Chainsaws chainsaws; 9 | 10 | public ChainsawBuilderImpl() { 11 | chainsaws = new Chainsaws(); 12 | } 13 | 14 | 15 | @Override 16 | public void battery() { 17 | chainsaws.setBattery("普通锂电池"); 18 | } 19 | 20 | @Override 21 | public void motor() { 22 | chainsaws.setMotor("普通铝电动机"); 23 | } 24 | 25 | @Override 26 | public void reductionGearbox() { 27 | chainsaws.setReductionGearbox("普通减速箱"); 28 | } 29 | 30 | @Override 31 | public void hood() { 32 | chainsaws.setHood("普通PVC塑料"); 33 | } 34 | 35 | @Override 36 | public void handle() { 37 | chainsaws.setHandle("普通PVC塑料"); 38 | } 39 | 40 | @Override 41 | public void switches() { 42 | chainsaws.setSwitches("普通拉线开关"); 43 | } 44 | 45 | @Override 46 | public void plug() { 47 | chainsaws.setPlug("普通三口插头"); 48 | } 49 | 50 | @Override 51 | public void circularSaw() { 52 | chainsaws.setCircularSaw("普通钢锯片"); 53 | } 54 | 55 | @Override 56 | public Chainsaws getChainsaws() { 57 | return chainsaws; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw/ChainsawBuilderImpl2.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw; 2 | 3 | /** 4 | * 链锯建筑者(具体建筑者) 5 | */ 6 | public class ChainsawBuilderImpl2 implements ChainsawBuilder{ 7 | 8 | private Chainsaws chainsaws; 9 | 10 | public ChainsawBuilderImpl2() { 11 | chainsaws = new Chainsaws(); 12 | } 13 | 14 | 15 | @Override 16 | public void battery() { 17 | chainsaws.setBattery("环保大容量锂电池"); 18 | } 19 | 20 | @Override 21 | public void motor() { 22 | chainsaws.setMotor("动力强耐高温散热好的纯铜电机"); 23 | } 24 | 25 | @Override 26 | public void reductionGearbox() { 27 | chainsaws.setReductionGearbox("减震变频高功率变速箱"); 28 | } 29 | 30 | @Override 31 | public void hood() { 32 | chainsaws.setHood("加厚加固耐磨抗打击防护罩"); 33 | } 34 | 35 | @Override 36 | public void handle() { 37 | chainsaws.setHandle("人体工体学包胶手柄"); 38 | } 39 | 40 | @Override 41 | public void switches() { 42 | chainsaws.setSwitches("调速防误触智能开关"); 43 | } 44 | 45 | @Override 46 | public void plug() { 47 | chainsaws.setPlug("环保防触电插头"); 48 | } 49 | 50 | @Override 51 | public void circularSaw() { 52 | chainsaws.setCircularSaw("高硬度锯片"); 53 | } 54 | 55 | @Override 56 | public Chainsaws getChainsaws() { 57 | return chainsaws; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw/Chainsaws.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw; 2 | 3 | /** 4 | * 产品(链锯) 5 | */ 6 | public class Chainsaws { 7 | 8 | // 蓄电池 9 | private String battery; 10 | // 电动机 11 | private String motor; 12 | // 减速箱 13 | private String reductionGearbox; 14 | // 防护罩 15 | private String hood; 16 | // 手柄 17 | private String handle; 18 | // 开关 19 | private String switches; 20 | // 插头 21 | private String plug; 22 | // 圆锯片 23 | private String circularSaw; 24 | 25 | 26 | public String getBattery() { 27 | return battery; 28 | } 29 | 30 | public void setBattery(String battery) { 31 | this.battery = battery; 32 | } 33 | 34 | public String getMotor() { 35 | return motor; 36 | } 37 | 38 | public void setMotor(String motor) { 39 | this.motor = motor; 40 | } 41 | 42 | public String getReductionGearbox() { 43 | return reductionGearbox; 44 | } 45 | 46 | public void setReductionGearbox(String reductionGearbox) { 47 | this.reductionGearbox = reductionGearbox; 48 | } 49 | 50 | public String getHood() { 51 | return hood; 52 | } 53 | 54 | public void setHood(String hood) { 55 | this.hood = hood; 56 | } 57 | 58 | public String getHandle() { 59 | return handle; 60 | } 61 | 62 | public void setHandle(String handle) { 63 | this.handle = handle; 64 | } 65 | 66 | public String getSwitches() { 67 | return switches; 68 | } 69 | 70 | public void setSwitches(String switches) { 71 | this.switches = switches; 72 | } 73 | 74 | public String getPlug() { 75 | return plug; 76 | } 77 | 78 | 79 | public void setPlug(String plug) { 80 | this.plug = plug; 81 | } 82 | 83 | public String getCircularSaw() { 84 | return circularSaw; 85 | } 86 | 87 | public void setCircularSaw(String circularSaw) { 88 | this.circularSaw = circularSaw; 89 | } 90 | 91 | 92 | @Override 93 | public String toString() { 94 | return "Chainsaws{" + 95 | "\n battery='" + battery + '\'' + 96 | ", motor='" + motor + '\'' + 97 | ", reductionGearbox='" + reductionGearbox + '\'' + 98 | ", hood='" + hood + '\'' + 99 | ", handle='" + handle + '\'' + 100 | ", switches='" + switches + '\'' + 101 | ", plug='" + plug + '\'' + 102 | ", circularSaw='" + circularSaw + '\'' + 103 | "链锯已经做好了\n" + '}'; 104 | } 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw/HardwareStoreBoss.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw; 2 | 3 | /** 4 | * 五金店老板(验收方) 5 | */ 6 | public class HardwareStoreBoss { 7 | 8 | // 电话通知建造方,查看进度如何了 9 | public Chainsaws notify(ChainsawBuilder builder){ 10 | 11 | // 蓄电池 12 | builder.battery(); 13 | // 电动机 14 | builder.motor(); 15 | // 减速箱 16 | builder.reductionGearbox(); 17 | // 防护罩 18 | builder.hood(); 19 | // 手柄 20 | builder.handle(); 21 | // 开关 22 | builder.switches(); 23 | // 插头 24 | builder.plug(); 25 | // 圆锯片 26 | builder.circularSaw(); 27 | return builder.getChainsaws(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw/Test.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw; 2 | 3 | /** 4 | * 测试类 5 | */ 6 | public class Test { 7 | 8 | public static void main(String[] args) { 9 | 10 | HardwareStoreBoss hardwareStoreBoss = new HardwareStoreBoss(); 11 | 12 | Chainsaws chainsaws = hardwareStoreBoss.notify(new ChainsawBuilderImpl()); 13 | System.out.println(chainsaws.toString()); 14 | 15 | // 新链锯 16 | Chainsaws chainsaws2 = hardwareStoreBoss.notify(new ChainsawBuilderImpl2()); 17 | System.out.println(chainsaws2.toString()); 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw2/ChainsawBuilder.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw2; 2 | 3 | /** 4 | * 链锯建筑者 5 | */ 6 | public interface ChainsawBuilder { 7 | 8 | // 蓄电池 9 | ChainsawBuilder battery(String name); 10 | // 电动机 11 | ChainsawBuilder motor(String name); 12 | // 减速箱 13 | ChainsawBuilder reductionGearbox(String name); 14 | // 防护罩 15 | ChainsawBuilder hood(String name); 16 | // 手柄 17 | ChainsawBuilder handle(String name); 18 | // 开关 19 | ChainsawBuilder switches(String name); 20 | // 插头 21 | ChainsawBuilder plug(String name); 22 | // 圆锯片 23 | ChainsawBuilder circularSaw(String name); 24 | 25 | // 获取链锯(产品)的实例 26 | Chainsaws getChainsaws(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw2/ChainsawBuilderImpl2.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw2; 2 | 3 | /** 4 | * 链锯建筑者(具体建筑者) 5 | */ 6 | public class ChainsawBuilderImpl2 implements ChainsawBuilder { 7 | 8 | private Chainsaws chainsaws; 9 | 10 | public ChainsawBuilderImpl2() { 11 | chainsaws = new Chainsaws(); 12 | } 13 | 14 | @Override 15 | public ChainsawBuilder battery(String name) { 16 | chainsaws.setBattery(name); 17 | return this; 18 | } 19 | 20 | @Override 21 | public ChainsawBuilder motor(String name) { 22 | chainsaws.setMotor(name); 23 | return this; 24 | } 25 | 26 | @Override 27 | public ChainsawBuilder reductionGearbox(String name) { 28 | chainsaws.setReductionGearbox(name); 29 | return this; 30 | } 31 | 32 | @Override 33 | public ChainsawBuilder hood(String name) { 34 | chainsaws.setHood(name); 35 | return this; 36 | } 37 | 38 | @Override 39 | public ChainsawBuilder handle(String name) { 40 | chainsaws.setHandle(name); 41 | return this; 42 | } 43 | 44 | @Override 45 | public ChainsawBuilder switches(String name) { 46 | chainsaws.setSwitches(name); 47 | return this; 48 | } 49 | 50 | @Override 51 | public ChainsawBuilder plug(String name) { 52 | chainsaws.setPlug(name); 53 | return this; 54 | } 55 | 56 | @Override 57 | public ChainsawBuilder circularSaw(String name) { 58 | chainsaws.setCircularSaw(name); 59 | return this; 60 | } 61 | 62 | @Override 63 | public Chainsaws getChainsaws() { 64 | return chainsaws; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw2/Chainsaws.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw2; 2 | 3 | /** 4 | * 产品(链锯) 5 | * 保持不变 6 | */ 7 | public class Chainsaws { 8 | 9 | // 蓄电池 10 | private String battery; 11 | // 电动机 12 | private String motor; 13 | // 减速箱 14 | private String reductionGearbox; 15 | // 防护罩 16 | private String hood; 17 | // 手柄 18 | private String handle; 19 | // 开关 20 | private String switches; 21 | // 插头 22 | private String plug; 23 | // 圆锯片 24 | private String circularSaw; 25 | 26 | 27 | public String getBattery() { 28 | return battery; 29 | } 30 | 31 | public void setBattery(String battery) { 32 | this.battery = battery; 33 | } 34 | 35 | public String getMotor() { 36 | return motor; 37 | } 38 | 39 | public void setMotor(String motor) { 40 | this.motor = motor; 41 | } 42 | 43 | public String getReductionGearbox() { 44 | return reductionGearbox; 45 | } 46 | 47 | public void setReductionGearbox(String reductionGearbox) { 48 | this.reductionGearbox = reductionGearbox; 49 | } 50 | 51 | public String getHood() { 52 | return hood; 53 | } 54 | 55 | public void setHood(String hood) { 56 | this.hood = hood; 57 | } 58 | 59 | public String getHandle() { 60 | return handle; 61 | } 62 | 63 | public void setHandle(String handle) { 64 | this.handle = handle; 65 | } 66 | 67 | public String getSwitches() { 68 | return switches; 69 | } 70 | 71 | public void setSwitches(String switches) { 72 | this.switches = switches; 73 | } 74 | 75 | public String getPlug() { 76 | return plug; 77 | } 78 | 79 | 80 | public void setPlug(String plug) { 81 | this.plug = plug; 82 | } 83 | 84 | public String getCircularSaw() { 85 | return circularSaw; 86 | } 87 | 88 | public void setCircularSaw(String circularSaw) { 89 | this.circularSaw = circularSaw; 90 | } 91 | 92 | 93 | @Override 94 | public String toString() { 95 | return "Chainsaws{" + 96 | "\n battery='" + battery + '\'' + 97 | ", motor='" + motor + '\'' + 98 | ", reductionGearbox='" + reductionGearbox + '\'' + 99 | ", hood='" + hood + '\'' + 100 | ", handle='" + handle + '\'' + 101 | ", switches='" + switches + '\'' + 102 | ", plug='" + plug + '\'' + 103 | ", circularSaw='" + circularSaw + '\'' + 104 | "链锯已经做好了\n" + '}'; 105 | } 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /design_patterns/src/com/lzw/part1_creation_mode/builder/chainsaw2/Test.java: -------------------------------------------------------------------------------- 1 | package com.lzw.part1_creation_mode.builder.chainsaw2; 2 | 3 | /** 4 | * 测试类 5 | */ 6 | public class Test { 7 | 8 | public static void main(String[] args) { 9 | ChainsawBuilderImpl2 chainsawBuilderImpl2 = new ChainsawBuilderImpl2(); 10 | Chainsaws chainsaws = chainsawBuilderImpl2.battery("环保大容量锂电池") 11 | .motor("动力强耐高温散热好的纯铜电机") 12 | .reductionGearbox("减震变频高功率变速箱") 13 | .hood("加厚加固耐磨抗打击防护罩") 14 | .handle("人体工体学包胶手柄") 15 | .switches("调速防误触智能开关") 16 | .plug("环保防触电插头") 17 | .circularSaw("高硬度锯片") 18 | .getChainsaws(); 19 | 20 | System.out.println(chainsaws.toString()); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /github_README/README文档的规范写法.md: -------------------------------------------------------------------------------- 1 | 本文原文请查看我的博客[开发工具总结(9)之 Github 开源项目的README文档的最全最规范写法](https://www.jianshu.com/p/813b70d5b0de) 2 | 3 | 看过很多开源库,发现有些库的文档写的一团糟,有的甚至就是一个标题,让你自己下载之后运行,自己摸索,看的很头疼。而那些使用量大的库的文档写的很标准,很详细,看的很舒服。 4 | 5 | README文档写的好的话能减少很多使用成本,能帮助这个库让更多人了解,更多的人用,可以说好的文档就是一个门面。 6 | **有好的 README 文档的项目不一定是一个好开源项目,但一个好开源项目一定有一个好的 README。** 7 | 8 | 下面就简单的总结一下README文档规范写法。(这只是我个人根据github上几百个大型开源库总结出来的,如你有更好的意见,欢迎留言。) 9 | 10 | ![](http://upload-images.jianshu.io/upload_images/6098829-9c4018b9d5b83c90.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 11 | 12 | 13 | #### 一、README文档的组成部分 14 | 15 | 看过很多开源框架的README文档,综合一下,大概有以下几部分组成: 16 | 17 | > * (一)国际化 18 | > * (二)项目工程介绍 19 | > * (三)项目的使用效果图 20 | > * (四)项目特点 21 | > * (五)项目的基本结构(架构) 22 | > * (六)集成方式 23 | > * (七)使用方法 24 | > * (八)混淆 25 | > * (九)关于作者/组织及交流方式等信息。 26 | > * (十)贡献者/贡献组织 27 | > * (十一)鸣谢 28 | > * (十二)版权信息 29 | 30 | ---- 31 | 32 | #### 二、下面就每个部分简单的分析一下: 33 | 34 | > (一)国际化 35 | 36 | github是面向全球的一个开源网站,所以不要局限于中文文档,建议写一个英文的README,让来自全球的人都能更方便的了解你的项目。推荐写法,在REAMDE开头写上国际化引用地址: 37 | 38 | 比如: 39 | ![国际化](https://upload-images.jianshu.io/upload_images/6098829-637dbfeb95d2b359.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 40 | 41 | 42 | 43 | 44 | > (二)项目工程介绍 45 | 46 | 项目介绍是必不可少的,它能让别人快速了解项目。项目介绍主要包括: 47 | * 项目名称、logo(没有logo就不写) 48 | * 这个开源项目是做什么的? 49 | * 这个项目是什么语言编写的? 50 | * 这个项目目前被多少人用到了,有多少好评等? 51 | * 项目维护、依赖更新状态(如果有的话,这也可以用)等 52 | * 项目可用版本及其他版本,以及每个版本的更新信息记录 53 | * Demo 或官网地址(如果有) 54 | 55 | 效果图如下所示: 56 | 57 | 英文版: 58 | 59 | ![英文版项目介绍](https://upload-images.jianshu.io/upload_images/6098829-548813a50d4c5fee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 60 | 61 | 62 | 中文版: 63 | 64 | ![中文版项目介绍](https://upload-images.jianshu.io/upload_images/6098829-88f5e591bc1e96fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 65 | 66 | ---- 67 | 68 | * 上述案例里面那些图标,请参考这个网站 [Shields.io](http://shields.io/),打开之后想用哪个直接复制就可以了,同时它也支持自定义样式。 69 | 70 | ---- 71 | 72 | > (三) 项目的使用效果图 73 | 74 | 如果是一些自定义控件或者项目的演示效果的,基本都会放上演示效果图,可以是图片,也可以是gif图。 75 | 建议:静态的页面的放截图,交互很复杂的建议放gif图。 如果功能比较多,建议每个功能一张效果图。 76 | 77 | 示例如下: 78 | 79 | **LoveHeartView使用示意图如下图所示:** 80 | ![](http://upload-images.jianshu.io/upload_images/6098829-79dedf212cd6bb20.gif?imageMogr2/auto-orient/strip) 81 | 82 | ---- 83 | 84 | > (四)项目特点 85 | 86 | 主要是介绍项目的特点,方便别人查看和了解该项目。 87 | 88 | 比如 **360的RePlugin框架的特点**就写的很详细: 89 | 90 | ![360的RePlugin的项目特点](https://upload-images.jianshu.io/upload_images/6098829-6662a9fe48a1927f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 91 | 92 | ---- 93 | 94 | > (五)项目的基本结构(架构) 95 | 96 | 这里主要介绍项目的各个组成部分,如果是框架,可以附带架构图解;如果是其他的,可以提供一些UML分析图,顺便分析一下源码也行的。 97 | 98 | 比如 **360的RePlugin架构图解** 如下所示: 99 | 100 | ![360的RePlugin架构图解](http://upload-images.jianshu.io/upload_images/6098829-54f47c3c98a123f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 101 | 102 | ![关于RePlugin架构的相关说明](https://upload-images.jianshu.io/upload_images/6098829-be8c24616dfcfafd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 103 | 104 | 105 | ---- 106 | 107 | > (六)集成方式 108 | 109 | 一般的项目传到jcenter上面或者AS插件传到jetbrains的话 一般会附带相关的集成方式的说明。(如果没有这些措施的话,这一步可以略过不看。) 110 | 111 | 比如 **okhttp** 就有详细的3种集成方式: 112 | 113 | 一个是下载Jar包;一个是引用Maven库;第三个是添加Gradle依赖: 114 | 115 | ![okhttp的集成方式](https://upload-images.jianshu.io/upload_images/6098829-31ba42f890757446.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 116 | 117 | 118 | ---- 119 | 120 | > **(七)使用方法** 121 | 122 | 一般的README必不可少的,最重要的就是用法,主要包括:安装,运行,编译,部署,debug,该github上的这个库如何在自己的项目中使用,以及需要注意的问题,版本更新适配问题等等。 123 | 124 | 这里就拿 **Glide** 举例说明,Glide里面有一个详细的wiki使用文档的,首页的README里面也写了一个简单的基本用法,如下图所示: 125 | 126 | ![Glide的基本用法](https://upload-images.jianshu.io/upload_images/6098829-d5f952798ab4644e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 127 | 128 | ---- 129 | 130 | > (八)混淆 131 | 132 | 一般来说,开源库都会设置一些混淆规则的,部分项目由于项目类型特殊之处,所以就没有混淆这一项,具体的看开源项目来定。 133 | 134 | 例如**LitePal这个开源库的混淆** 如下图所示: 135 | 136 | ![LitePal混淆规则](https://upload-images.jianshu.io/upload_images/6098829-a7b9509d9c779e5c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 137 | 138 | ---- 139 | 140 | > (九)关于作者/组织及交流方式等信息。 141 | 142 | 这个就很灵活了,不是每一个必备,当然写出来方便大家联系作者,也是很好的。可以写一下作者或者组织的联系方式,微信,邮箱,博客,微博,甚至支付宝转账二维码等都是可以放上去的。 143 | 144 | 例如 **blankj的AndroidUtilCode这个库**为例,为了避免打广告嫌疑,我做了打码处理: 145 | 146 | ![](https://upload-images.jianshu.io/upload_images/6098829-254508dbb30b7209.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 147 | 148 | > (十)贡献者/贡献组织 149 | 150 | 比如 **谷歌推出的 [sample](https://github.com/googlesamples/android-architecture) 里面就有贡献者/贡献组织信息**,如下图所示: 151 | 152 | ![谷歌推出的sample的贡献者/贡献组织信息](https://upload-images.jianshu.io/upload_images/6098829-0d7345df341a1465.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 153 | 154 | > (十一)鸣谢 155 | 156 | 这个主要是引用了哪些开源技术,这里可以做一些鸣谢,表示对别人的尊重,其实也是一个引用声明,避免因为版权而引起不必要的纠纷。 157 | 158 | 例如:我写的这个库 https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/summary.md 里面就写了鸣谢。 159 | 160 | ![https://github.com/AweiLoveAndroid/CommonDevKnowledge里面的鸣谢](https://upload-images.jianshu.io/upload_images/6098829-3c087d12e4c36f63.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 161 | 162 | 163 | ---- 164 | 165 | > (十二)版权信息 166 | 167 | 版本很重要,开源许可证很重要,如果没有生命版权,可能会因为一些侵权行为而无法很好的维权,版权信息可以保护作者的权益(个人理解)。 168 | 169 | 世界上的开源许可证,大概有上百种。很少有人搞得清楚它们的区别。最流行的有六种:**GPL、BSD、MIT、Mozilla、Apache、LGPL** 170 | 171 | 乌克兰程序员Paul Bagwell,画了一张分析图,说明应该怎么选择。这是我见过的最简单的讲解,只用两分钟,你就能搞清楚这 [六种许可证之间的最大区别](http://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html)。 172 | 173 | ![六种开源许可证之间的区别](https://upload-images.jianshu.io/upload_images/6098829-2bbe539c752db104.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 174 | 175 | 比如 **Picasso 里面的版权信息**,如下图所示: 176 | 177 | ![Picasso 里面的版权信息](https://upload-images.jianshu.io/upload_images/6098829-51924243fe916e75.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 178 | -------------------------------------------------------------------------------- /interview/answers/HR提出的面试问题参考解答.md: -------------------------------------------------------------------------------- 1 | ##### HR提出的面试问题参考答案(待完善) 2 | 3 | 综合了一下网上的资料,主要从以下几个方面去考查: 4 | 5 | **关于实习:** 6 | 7 | * 公司实习最大的收获是什么? 8 | * 实习过程中周围同事/同学有哪些值得学习的地方? 9 | * 是否可以实习,可以实习多久? 10 | * 你的学习方法是什么样的?实习过程中如何学习?实习项目中遇到的最大困难是什么以及如何解决的? 11 | * 其他同学都投了哪些公司? 12 | 13 | * (1)个人的基本了解,自我介绍,优缺点,学历,工作地,教育背景等。 14 | 15 | > 评价下自己,评价下自己的技术水平,个人代码量如何? 16 | 17 | > 你朋友对你的评价? 18 | 19 | **回答提示:** 想从侧面了解一下你的性格及与人相处的问题。 20 | 回答样本一:我的朋友都说我是一个可以信赖的人。因为,我一旦答应别人的事情,就一定会做到。如果我做不到,我就不会轻易许诺。 21 | 回答样本二:我觉的我是一个比较随和的人,与不同的人都可以友好相处。在我与人相处时,我总是能站在别人的角度考虑问题。 22 | 23 | > 自己的优点和缺点是什么?并举例说明? 24 | 25 | **回答提示:**沉著冷静、条理清楚、立场坚定、顽强向上、乐于助人和关心他人、适应能力和幽默感、乐观和友爱。稳重 26 | 27 | > 你觉得你个性上最大的优点是什么? 28 | 29 | **回答提示:**可以突出一些积极的正面的特点,比如:沉著冷静、条理清楚、立场坚定、顽强向上、乐于助人和关心他人、适应能力和幽默感、乐观和友爱,稳重等。 30 | **我本人的示例:**` 1.我的求知欲望比较强, 有好奇心。从小到大我一直喜欢读书,现在工作了也特别喜欢钻研新技术。对我来说, 钻研技术既是工作也是乐趣,工作之余,我喜欢写博客,把我研究的新技术分享给别人。2.我善于分享,积极参加公司的技术分享交流,我认为技术分享既能提高自己的表达能力,也能让大家学到技术,共同提高,是一件很有意义的事情,也是我一直在做的。我也积极参加一些Android线下论坛,跟大家探讨技术。3.我爱思考,爱动脑筋,总想把事情做得更好。` 31 | 32 | > 说说你最大的缺点? 33 | 34 | **回答提示:**这个问题企业问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,企业肯定不会录用你。绝对不要自作聪明地回答“我最大的缺点是过于追求完美”,有的人以为这样回答会显得自己比较出色,但事实上,他已经岌岌可危了。也喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分,企业喜欢聪明的求职者。 35 | **示例:**`喜欢追求细节导致项目/作业未能按期完成。通过时间管理能力改变工作方式,先完成框架再改善细节得以解决;2)不知如何拒绝,同事要求帮忙一概揽下,影响自身工作进度。通过多任务处理能力设定优先顺序,以该优先顺序表向求助同事展示自己手上工作,并给其一个自己在何时可以给予帮助的时间估计,让求助人自行决定是否求助,问题解决。` 36 | 37 | > 最能概括你自己的三个词是什么? 38 | 39 | **回答提示:**我经常用的三个词是:适应能力强,有责任心和做事有始终,结合具体例子向主考官解释。 40 | 41 | > 何时可以到职? 42 | 43 | **回答提示:**大多数企业会关心就职时间,最好是回答“如果被录用的话,到职日可按公司规定上班”,但如果还未辞去上一个工作、上班时间又太近,似乎有些强人所难,因为交接至少要一个月的时间,应进一步说明原因,录取公司应该会通融的。 44 | 45 | > 你并非毕业于名牌院校? 46 | 47 | **回答提示:**是否毕业于名牌院校不重要,重要的是有能力完成您交给我的工作,我想我更适合贵公司这个职位。 48 | 49 | > 说说你的家庭? 50 | 51 | **回答提示:**企业面试时询问家庭问题不是非要知道求职者家庭的情况,探究隐私,企业不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。企业希望听到的重点也在于家庭对求职者的积极影响。企业最喜欢听到的是:我很爱我的家庭,我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到我父亲起早贪黑,每天工作特别勤劳,他的行动无形中培养了我认真负责的态度和勤劳的精神。我母亲为人善良,对人热情,特别乐于助人,所以在单位人缘很好,她的一言一行也一直在教导我做人的道理。企业相信,和睦的家庭关系对一个人的成长有潜移默化的影响。 52 | 53 | > 除了本公司外,还应聘了哪些公司?(类似问题:当前的offer状况) 54 | 55 | **回答提示:**很奇怪,这是相当多公司会问的问题,其用意是要概略知道应徵者的求职志向,所以这并非绝对是负面答案,就算不便说出公司名称,也应回答“销售同种产品的公司”,如果应聘的其他公司是不同业界,容易让人产生无法信任的感觉。 56 | 57 | > 通过哪些渠道了解的招聘信息? 58 | 59 | **回答提示:**面试官一个是要统计一下是什么渠道招聘有效,再一个看看是不是内推的,很多公司内推都有奖励的。这种问题没什么要讲究的,是从哪里得知的就直接回答就好。 60 | 61 | > 你的业余爱好是什么? 62 | 63 | **回答提示:**找一些富于团体合作精神的,这里有一个真实的故事:有人被否决掉,因为他的爱好是深海潜水。主考官说:因为这是一项单人活动,我不敢肯定他能否适应团体工作。 64 | 65 | > 你做过的哪件事最令自己感到骄傲? 66 | 67 | **回答提示:**这是考官给你的一个机会,让你展示自己把握命运的能力。这会体现你潜在的领导能力以及你被提升的可能性。假如你应聘于一个服务性质的单位,你很可能会被邀请去午餐。记住:你的前途取决于你的知识、你的社交能力和综合表现。 68 | * 如果BATH都给了offer该如何选? 69 | * 你对一份工作更看重哪些方面?平台,技术,氛围,城市,还是money? 70 | * 你看中公司的什么?或者公司的那些方面最吸引你? 71 | * 理想薪资范围;杭州岗和北京岗选哪个? 72 | * 理想中的工作环境是什么? 73 | * 家人对你的工作期望及自己的工作期望 74 | 75 | * (2)灵活应变能力(也涉及工作态度) 76 | 77 | > 为什么要离职? 78 | 79 | **回答提示:**回答这个问题时一定要小心,就算在前一个工作受到再大的委屈,对公司有多少的怨言,都千万不要表现出来,尤其要避免对公司本身主管的批评,避免面试官的负面情绪及印象。建议此时最好的回答方式是将问题归咎在自己身上,例如觉得工作没有学习发展的空间,自己想在面试工作的相关产业中多加学习,或是前一份工作与自己的生涯规划不合等等,回答的答案最好是积极正面的。 80 | 回答样本:我希望能获得一份更好的工作,如果机会来临,我会抓住。我觉得目前的工作,已经达到顶峰,即没有升迁机会。 81 | 82 | > 您在前一家公司的离职原因是什么?(您为何要离开目前服务的这家公司?) 83 | 84 | **回答提示:**一最重要的是:应聘者要使找招聘单位相信,应聘者在过往的单位的“离职原因”在此家招聘单位里不存在。二避免把“离职原因”说得太详细、太具体。③不能掺杂主观的负面感受,如“太辛苦”、“人际关系复杂”、“管理太混乱”、“公司不重视人才”、“公司排斥我们某某的员工”等。四但也不能躲闪、回避,如“想换换环境”、“个人原因”等。伍不能涉及自己负面的人格特征,如不诚实、懒惰、缺乏责任感、不随和等。⑥尽量使解释的理由为应聘者个人形象添彩。七相关例子:如“我离职是因为这家公司倒闭;我在公司工作了三年多,有较深的感情;从去年始,由于市场形势突变,公司的局面急转直下;到眼下这一步我觉得很遗憾,但还要面对显示,重新寻找能发挥我能力的舞台。”同一个面试问题并非只有一个答案,而同一个答案并不是在任何面试场合都有效,关键在应聘者掌握了规律后,对面试的具体情况进行把握,有意识地揣摩面试官提出问题的心理背景,然后投其所好。 85 | 分析:除非是薪资太低,或者是最初的工作,否则不要用薪资作为理由。“求发展”也被考官听得太多,离职理由要根据每个人的真实离职理由来设计,但是在回答时一定要表现得真诚。实在想不出来的时候,家在外地可以说是因为家中有事,须请假几个月,公司又不可能淮假,所以辞职,这个答案一般面试官还能接受。 86 | 87 | 2.您跟您的主管或直接上司有没有针对以上离职原因的这些问题沟通过?如果没有请说明原因。如果有请说一下过程和结果? 88 | 3.除了简历上的工作经历,您还会去关注哪些领域? 89 | 4.您觉得你关注的这些领域跟您目前从事的职业有哪些利弊关系?如果有请说明利弊关系。 90 | 5.您不觉得您的知识结构有些狭窄或兴趣比较贫乏,说说未来改善的计划? 91 | 6.您在选择工作中更看重的是什么?(可能是成长空间、培训机会、发挥平台、薪酬等答案) 92 | 7.您可不可以说说您在薪酬方面的心里预期?(如果问题6的回答中薪酬不是排在第一,这个问题基本会被问到) 93 | 8.那您刚才的意思也可以理解为:薪酬方面可以适当降低于您的心里预期,对吗?(这是针对问题7的回答继续提问的,问这个问题说明求职者给出的薪酬可以综合考虑,有让步空间) 94 | 9.有人说挣未来比挣钱更为重要,您怎么理解?(这是针对问题7的回答继续提问的,问这个问题说明求职者针对薪酬这个问题不肯让步) 95 | 10.有人说挣未来比挣钱更为重要,您怎么理解?(如果问题6的回答的答案中,薪酬排在第一,一般会被问这个问题) 96 | 11.假设,某一天,在工作办公室走廊,您和一位同事正在抱怨上级陈某平时做事缺乏公平性,恰巧被陈某听到,您会怎么办? 97 | 12.您怎么看待加班问题? 98 | 13.怎么样处理工作和生活的关系?怎么处理在工作中遇到困难?请举例说明 99 | 100 | > 谈谈你对跳槽的看法? 101 | 102 | **回答提示:**一正常的“跳槽”能促进人才合理流动,应该支持。二频繁的跳槽对单位和个人双方都不利,应该反对。 103 | 104 | > 怎样看待学历和能力? 105 | 106 | **回答提示:**学历我想只要是大学专科的学历,就表明觉得我具备了根本的学习能力。剩下的,你是学士也好,还是博士也好,对于这一点的讨论,不是看你学了多少知识,而是看你在这个领域上发挥了什么,也就是所说的能力问题。一个人工作能力的高低直接决定其职场命运,而学历的高低只是进入一个企业的敲门砖,如果贵公司把学历卡在博士上,我就无法进入贵公司,当然这不一定只是我个人的损失,如果一个专科生都能完成的工作,您又何必非要招聘一位博士生呢? 107 | 108 | > 你有哪些要问我的? 109 | 110 | * (3)社交能力和人际关系 111 | 1.在您的现实生活中,您最不喜欢和什么样的人共事?为什么?举例说明。 112 | 2.在您认识的人中,有没有人不喜欢您?为什么不喜欢您?请举例说明。 113 | 3.当老板/上司/同事/客户误会你,你会怎么办? 114 | 4.当你发现其他部门的工作疏漏已经影响到您的工作绩效时,您怎么办? 115 | 5.您希望在什么样的领导下工作? 116 | 117 | * (4)判断力,情绪控制力(压力承受力) 118 | 1.我们工作与生活历程并不是一帆风顺的,谈谈您的工作或生活中出现的挫折或低潮期,您如何克服? 119 | 2.假如您的上司是一个非常严厉、领导手腕强硬,时常给您巨大压力的人,您觉得这种领导方式对您有何利、弊? 120 | 3.您的领导给您布置了一项您以前从未触及过的任务,您打算如何去完成它?(如果有类似的经历说说完成的经历。) 121 | 4.谈谈您以往职业生涯中最有压力的一、两件事,并说说是如何克服的。 122 | 5.谈谈您以往职业生涯中令您有成就感的一、两件事,并说说它给您的启示。 123 | 6.讲一件你印象最深的一件事情 124 | 7.介绍一个你影响最深的项目 125 | 126 | * (5)行动与协调能力、沟通能力 127 | 1.您觉得自己的个性适合井然有序的工作环境还是灵活自如的工作环境。 128 | 2.请您举一个例子,说明在完成一项重要任务时,您是怎样和他人进行有效合作的。 129 | 3.请描述当你意识到工作进程中出现问题了,你是如何处理的? 130 | 4.请说出一个工作进程中的确切目标,你怎样确保达到此既定目标。 131 | 5.请您举一个例子,说明在完成一项重要任务时,您是怎样和他人进行有效合作的。 132 | 6.当你要牺牲自己的某些方面与他人共事时,你会怎么办? 133 | 7.有时团队成员不能有效共事,当遇到这种问题时你是怎么处理的?你又是如何改善这类情况的? 134 | 8.我们有时不得不与自己不喜欢的人在一个团队工作,如果遇到这样的情况你会怎么办? 135 | 136 | * (6)责任心、纪律性及归属感 137 | 1.您对委任的任务完成不了时如何处理? 2.请描述一下您以往所就职公司中您认为最适合您自己的企业文化的特色 138 | 3.描述一下您对上司所布置任务的完成思想与过程。 139 | 4.当您所在的集体处于竞争劣势时,您有什么想法和行动? 140 | 5.往往跨组织的任务中,由于涉及过多成员最后易形成责任者缺位现象,您如果身处其境会是什么心态? 141 | 6.您每一次离职时有没有过失落感?您跟过去就职过的公司的一、两个上司或同事还有联系吗?并说说他们目前的处境。 142 | 143 | * (7)管理能力(面试管理岗会被问到) 144 | 1.您的下属未按期完成您所布置给他的任务,如果您的上司责怪下来,您认为这是谁的责任,为什么? 145 | 2.在您以往的工作中是如何去约束部属的,是如何去调动他们积极性的? 146 | 3.举个例子来说明一下您曾经做过的一个成功计划及实施过程。工作中您发现自己的实施结果与事先计划出现较大的偏差,你将如何去行动? 147 | 4.说说您对下属布置的任务在时间方面是如何要求的? 148 | 5.说说您在完成上司布置的任务时,在时间方面是如何要求自己的? 149 | 6.您以往在领导岗位中,一个月内分别有哪些主要的工作任务? 150 | 7.当您发现您的部属目前士气较低沉,您一般从哪些方面去调动? 151 | 8.说说您在以往领导岗位中出现管理失控的事例及事后的原因分析。您的部属在一个专业的问题上跟您发生争议,您如何对待这种事件? 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | > 你最擅长的技术方向是什么?(类似问题:介绍你最热爱最擅长的专业领域) 160 | 161 | **回答提示:**说和你要应聘的职位相关的课程,表现一下自己的热诚没有什么坏处。 162 | 163 | > 如果你做的一项工作受到上级领导的表扬,但你主管领导却说是他做的,你该怎样? 164 | 165 | **回答提示:**我首先不会找那位上级领导说明这件事,我会主动找我的主管领导来沟通,因为沟通是解决人际关系的最好办法,但结果会有两种:一我的主管领导认识到自己的错误,我想我会视具体情况决定是否原谅他。二他更加变本加厉的来威胁我,那我会毫不犹豫地找我的上级领导反映此事,因为他这样做会造成负面影响,对今后的工作不利。 166 | 167 | > 在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做?(类似问题:与上级意见不一致时,你将怎么办?) 168 | 169 | **回答提示:**一.原则上我会尊重和服从领导的工作安排,同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法。二如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作。③.还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见,如领导仍固执己见,我会毫不犹豫地再向上级领导反映。 170 | 171 | > 假设你在某单位工作,成绩比较突出,得到领导的肯定。但同时你发现同事们越来越孤立你,你怎么看这个问题?你淮备怎么办? 172 | 173 | **回答提示:**一成绩比较突出,得到领导的肯定是件好事情,以后更加努力。二检讨一下自己是不是对工作的热心度超过同事间交往的热心了,加强同事间的交往及共同的兴趣爱好。③工作中,切勿伤害别人的自尊心。四不再领导前拨弄是非。 174 | 175 | > 工作中你难以和同事、上司相处,你该怎么办? 176 | 177 | **回答提示:**一我会服从领导的指挥,配合同事的工作。二我会从自身找原因,仔细分析是不是自己工作做得不好让领导不满意,同事看不惯。还要看看是不是为人处世方面做得不好,如果是这样的话 我会努力改正。③如果我找不到原因,我会找机会跟他们沟通,请他们指出我的不足,有问题就及时改正。四作为优秀的员工,应该时刻以大局为重,即使在一段时间内,领导和同事对我不理解,我也会做好本职工作,虚心向他们学习,我相信,他们会看见我在努力,总有一天会对我微笑的。 178 | 179 | 180 | 181 | 182 | * 说一件最能证明你能力的事情 183 | 184 | > 就你申请的这个职位,你认为你还欠缺什么? 185 | 186 | **回答提示:**企业喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:“对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。”企业喜欢能够巧妙地躲过难题的求职者。 187 | 188 | * 如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办? 189 | * 项目中遇到最大的困难是什么?如何解决的? 190 | 191 | * 你的职业规划以及个人目标、未来发展路线及求职定位 192 | 193 | > 在五年的时间内,你的职业规划? 194 | 195 | **回答提示:**这是每一个应聘者都不希望被问到的问题,但是几乎每个人都会被问到,比较多的答案是“管理者”。但是近几年来,许多公司都已经建立了专门的技术途径。这些工作地位往往被称作“顾问”、“参议技师”或“高级软件工程师”等等。当然,说出其他一些你感兴趣的职位也是可以的,比如产品销售部经理,生产部经理等一些与你的专业有相关背景的工作。要知道,考官总是喜欢有进取心的应聘者,此时如果说“不知道”,或许就会使你丧失一个好机会。最普通的回答应该是“我淮备在技术领域有所作为”或“我希望能按照公司的管理思路发展”。 196 | 197 | > 说说你对行业、技术发展趋势的看法? 198 | 199 | **回答提示:**企业对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。企业认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,企业欢迎进入企业的人是“知己”,而不是“盲人”。 200 | 201 | > 如果你在这次面试中没有被录用,你怎么打算? 202 | 203 | **回答提示:**现在的社会是一个竞争的社会,从这次面试中也可看出这一点,有竞争就必然有优劣,有成功必定就会有失败。往往成功的背后有许多的困难和挫折,如果这次失败了也仅仅是一次而已,只有经过经验经历的积累才能塑造出一个完全的成功者。我会从以下几个方面来正确看待这次失败:一要敢于面对,面对这次失败不气馁,接受已经失去了这次机会就不会回头这个现实,从心理意志和精神上体现出对这次失败的抵抗力。要有自信,相信自己经历了这次之后经过努力一定能行,能够超越自我。二善于反思,对于这次面试经验要认真总结,思考剖析,能够从自身的角度找差距。正确对待自己,实事求是地评价自己,辩证的看待自己的长短得失,做一个明白人。③走出阴影,要克服这一次失败带给自己的心理压力,时刻牢记自己弱点,防患于未然,加强学习,提高自身素质。四认真工作,回到原单位岗位上后,要实实在在、踏踏实实地工作,三十六行、行行出状元,争取在本岗位上做出一定的成绩。伍再接再厉,成为国家公务员一直是我的梦想,以后如果有机会我仍然后再次参加竞争。 204 | 205 | 206 | 207 | 208 | 209 | > 假如你晚上要去送一个出国的同学去机场,可单位临时有事非你办不可,你怎么办? 210 | 211 | **回答提示:**我觉得工作是第一位的,但朋友间的情谊也是不能偏废的,这个问题我觉得要按照当时具体的情况来决定。一如果我的朋友晚上9点中的飞机,而我的加班八点就能够完成的话,那就最理想了,干完工作去机场,皆大欢喜。二如果说工作不是很紧急,加班仅仅是为了明天上班的时候能把报告交到办公室,那完全可以跟领导打声招呼,先去机场然后回来加班,晚点睡就是了。③如果工作很紧急,两者不可能兼顾的情况下,我觉得可以由两种选择。(1)如果不是全单位都加班的话,是不是可以要其他同事来代替以下工作,自己去机场,哪怕就是代替你离开的那一会儿。(2)如果连这一点都做不到的话,那只好忠义不能两全了,打电话给朋友解释一下,相信他会理解,毕竟工作做完了就完了,朋友还是可以再见面的。 212 | 213 | 214 | 215 | 216 | 217 | * 如果你的工作出现失误,给本公司造成经济损失,你认为该怎么办? 218 | 219 | * 若上司在公开会议上误会你了,该如何解决? 220 | 221 | > 新到一个部门,一天一个客户来找你解决问题,你努力想让他满意,可是始终达不到群众的满意,他投诉你们部门工作效率低,你这个时候怎么作? 222 | 223 | **回答提示:**(1)首先,我会保持冷静。作为一名工作人员,在工作中遇到各种各样的问题是正常的,关键是如何认识它,积极应对,妥善处理。(2)其次,我会反思一下客户不满意的原因。一是看是否是自己在解决问题上的确有考虑的不周到的地方,二是看是否是客户不太了解相关的服务规定而提出超出规定的要求,三是看是否是客户了解相关的规定,但是提出的要求不合理。(3)再次,根据原因采取相对的对策。如果是自己确有不周到的地方,按照服务规定作出合理的安排,并向客户作出解释;如果是客户不太了解政策规定而造成的误解,我会向他作出进一步的解释,消除他的误会;如果是客户提出的要求不符合政策规定,我会明确地向他指出。(4)再次,我会把整个事情的处理情况向领导作出说明,希望得到他的理解和支持。(5)我不会因为客户投诉了我而丧失工作的热情和积极性,而会一如既往地牢记为客户服务的宗旨,争取早日做一名领导信任、公司放心、客户满意的职员。 224 | 225 | 226 | 227 | 228 | > 请你自我介绍一下你自己? 229 | 230 | **回答提示:** 一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有。其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理企业才会相信。 231 | 企业很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句“谢谢”,企业喜欢有礼貌的求职者。 232 | 233 | > 你对加班的看法? 234 | 235 | **回答提示:**实际上好多公司问这个问题,并不证明一定要加班,只是想测试你是否愿意为公司奉献。 236 | 回答样本:如果是工作需要我会义不容辞加班,我现在单身,没有任何家庭负担,可以全身心的投入工作。但同时,我也会提高工作效率,减少不必要的加班。 237 | 238 | > 你对薪资的要求? 239 | 240 | **回答提示:**如果你对薪酬的要求太低,那显然贬低自己的能力;如果你对薪酬的要求太高,那又会显得你分量过重,公司受用不起。一些雇主通常都事先对求聘的职位定下开支预算,因而他们第一次提出的价钱往往是他们所能给予的最高价钱,他们问你只不过想证实一下这笔钱是否足以引起你对该工作的兴趣。如果你自己必须说出具体数目,请不要说一个宽泛的范围,那样你将只能得到最低限度的数字。最好给出一个具体的数字,这样表明你已经对当今的人才市场作了调查,知道像自己这样学历的雇员有什么样的价值。 241 | 回答样本一:我对工资没有硬性要求,我相信贵公司在处理我的问题上会友善合理。我注重的是找对工作机会,所以只要条件公平,我则不会计较太多。 242 | 回答样本二:我受过系统的软件编程的训练,不需要进行大量的培训,而且我本人也对编程特别感兴趣。因此,我希望公司能根据我的情况和市场标淮的水平,给我合理的薪水。 243 | 244 | 245 | 246 | 247 | > 你还有什么问题要问吗? 248 | 249 | **回答提示:**企业的这个问题看上去可有可无,其实很关键,企业不喜欢说“没问题”的人,因为其很注重员工的个性和创新能力。企业不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?企业将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。 250 | 企业文化,项目的方向。公司发展方向 251 | 252 | > 如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办? 253 | 254 | **回答提示:**一段时间发现工作不适合我,有两种情况:一如果你确实热爱这个职业,那你就要不断学习,虚心向领导和同事学习业务知识和处事经验,了解这个职业的精神内涵和职业要求,力争减少差距;二你觉得这个职业可有可无,那还是趁早换个职业,去发现适合你的,你热爱的职业,那样你的发展前途也会大点,对单位和个人都有好处。 255 | 256 | 257 | 258 | > 如果你的工作出现失误,给本公司造成经济损失,你认为该怎么办? 259 | 260 | **回答提示:**一我本意是为公司努力工作,如果造成经济损失,我认为首要的问题是想方设法去弥补或挽回经济损失。如果我无能力负责,希望单位帮助解决。二分清责任,各负其责,如果是我的责任,我甘愿受罚;如果是一个我负责的团队中别人的失误,也不能幸灾乐祸,作为一个团队,需要互相提携共同完成工作,安慰同事并且帮助同事查找原因总结经验。 261 | ③总结经验教训,一个人的一生不可能不犯错误,重要的是能从自己的或者是别人的错误中吸取经验教训,并在今后的工作中避免发生同类的错误。检讨自己的工作方法、分析问题的深度和力度是否不够,以致出现了本可以避免的错误。 262 | 263 | 264 | 265 | 266 | 267 | > 你最近是否参加了培训课程?谈谈培训课程的内容。是公司资助还是自费参加? 268 | 269 | **回答提示:**公司组织参加,就是传智播客的培训课程(可以多谈谈自己学的技术)。 270 | 271 | > 你对于我们公司了解多少? 272 | 273 | **回答提示:**在去公司面试前上网查一下该公司主营业务。如回答:贵公司有意改变策略,加强与国外大厂的OEM合作,自有品牌的部分则透过海外经销商。 274 | 275 | > 请说出你选择这份工作的动机? 276 | 277 | **回答提示:**这是想知道面试者对这份工作的热忱及理解度,并筛选因一时兴起而来应试的人,如果是无经验者,可以强调“就算职种不同,也希望有机会发挥之前的经验”。 278 | 279 | 280 | 281 | > 你能为我们公司带来什么呢? 282 | 283 | **回答提示:**企业很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:“就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益”。企业喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:“我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。”等等。 284 | 285 | 286 | 287 | 288 | > 作为被面试者给我打一下分? 289 | 290 | **回答提示:**试著列出四个优点和一个非常非常非常小的缺点(可以抱怨一下设施,没有明确责任人的缺点是不会有人介意的)。 291 | 292 | > 你怎么理解你应聘的职位? 293 | 294 | **回答提示:**把岗位职责和任务及工作态度阐述一下。 295 | 296 | > 喜欢这份工作的哪一点? 297 | 298 | **回答提示:**相信其实大家心中一定都有答案了吧!每个人的价值观不同,自然评断的标淮也会不同,但是,在回答面试官这个问题时可不能太直接就把自己心理的话说出来,尤其是薪资方面的问题,不过一些无伤大雅的回答是不错的考虑,如交通方便,工作性质及内容颇能符合自己的兴趣等等都是不错的答案,不过如果这时自己能仔细思考出这份工作的与众不同之处,相信在面试上会大大加分。 299 | 300 | 301 | 302 | 303 | > 对工作的期望与目标何在? 304 | 305 | **回答提示:**这是面试者用来评断求职者是否对自己有一定程度的期望、对这份工作是否了解的问题。对于工作有确实学习目标的人通常学习较快,对于新工作自然较容易进入状况,这时建议你,最好针对工作的性质找出一个确实的答案,如业务员的工作可以这样回答:“我的目标是能成为一个超级业务员,将公司的产品广泛的推销出去,达到最好的业绩成效;为了达到这个目标,我一定会努力学习,而我相信以我认真负责的态度,一定可以达到这个目标。”其他类的工作也可以比照这个方式来回答,只要在目标方面稍微修改一下就可以了。 306 | 307 | 308 | 309 | 310 | 311 | > 你欣赏哪种性格的人? 312 | 313 | **回答提示:**诚实、不死板而且容易相处的人、有“实际行动”的人。 314 | 315 | > 你通常如何处理别人的批评? 316 | 317 | **回答提示:**一沉默是金,不必说什么,否则情况更糟,不过我会接受建设性的批评。二我会等大家冷静下来再讨论。 318 | 319 | > 怎样对待自己的失败? 320 | 321 | **回答提示:**我们大家生来都不是十全十美的,我相信我有第二个机会改正我的错误。 322 | 323 | > 什么会让你有成就感? 324 | 325 | **回答提示:**为贵公司竭力效劳,尽我所能,完成一个项目。 326 | 327 | > 眼下你生活中最重要的是什么? 328 | 329 | **回答提示:**对我来说,能在这个领域找到工作是最重要的,能在贵公司任职对我说最重要。 330 | 331 | > 你为什么愿意到我们公司来工作? 332 | 333 | **回答提示:**对于这个问题,你要格外小心,如果你已经对该单位作了研究,你可以回答一些详细的原因,像“公司本身的高技术开发环境很吸引我。”、“我同公司出生在同样的时代,我希望能够进入一家与我共同成长的公司。”、“你们公司一直都稳定发展,在近几年来在市场上很有竞争力。”、“我认为贵公司能够给我提供一个与众不同的发展道路。”这都显示出你已经做了一些调查,也说明你对自己的未来有了较为具体的远景规划。 334 | 335 | > 你和别人发生过争执吗?你是怎样解决的? 336 | 337 | **回答提示:**这是面试中最险恶的问题,其实是考官布下的一个陷阱,千万不要说任何人的过错,应知成功解决矛盾是一个协作团体中成员所必备的能力。假如你工作在一个服务行业,这个问题简直成了最重要的一个环节。你是否能获得这份工作,将取决于这个问题的回答。考官希望看到你是成熟且乐于奉献的。他们通过这个问题了解你的成熟度和处世能力。在没有外界干涉的情况下,通过妥协的方式来解决才是正确答案。 338 | 339 | 340 | 341 | 342 | 343 | > 对这项工作,你有哪些可预见的困难? 344 | 345 | **回答提示:**一不宜直接说出具体的困难,否则可能令对方怀疑应聘者不行。二可以尝试迂回战术,说出应聘者对困难所持有的态度——工作中出现一些困难是正常的,也是难免的,但是只要有坚忍不拔的毅力、良好的合作精神以及事前周密而充分的淮备,任何困难都是可以克服。 346 | 分析:一般问这个问题,面试者的希望就比较大了,因为已经在谈工作细节,但常规思路中的回答,又被面试官“骗”了。当面试官询问这个问题的时候,有两个目的。第一,看看应聘者是不是在行,说出的困难是不是在这个职位中一般都不可避免的问题。第二,是想看一下应聘者解决困难的手法对不对,及公司能否提供这样的资源。而不是想了解应聘者对困难的态度。 347 | 348 | > 如果我录用你,你将怎样开展工作? 349 | 350 | **回答提示:** 一如果应聘者对于应聘的职位缺乏足够的了解,最好不要直接说出自己开展工作的具体办法。二可以尝试采用迂回战术来回答,如“首先听取领导的指示和要求,然后就有关情况进行了解和熟悉,接下来制定一份近期的工作计划并报领导批淮,最后根据计划开展工作。”。 351 | 分析:这个问题的主要目的也是了解应聘者的工作能力和计划性、条理性,而且重点想要知道细节。如果向思路中所讲的迂回战术,面试官会认为回避问题,如果引导了几次仍然是回避的话,此人绝对不会录用了。 352 | 353 | > 你希望与什么样的上级共事? 354 | 355 | **回答提示:**一通过应聘者对上级的“希望”可以判断出应聘者对自我要求的意识,这既上一个陷阱,又是一次机会。二最好回避对上级具体的希望,多谈对自己的要求。③如“做为刚步入社会的新人,我应该多要求自己尽快熟悉环境、适应环境,而不应该对环境提出什么要求,只要能发挥我的专长就可以了。 356 | 分析:这个问题比较好的回答是,希望我的上级能够在工作中对我多指导,对我工作中的错误能够立即指出。总之,从上级指导这个方面谈,不会有大的批漏。 357 | 358 | > 在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做? 359 | 360 | **回答提示:**一.原则上我会尊重和服从领导的工作安排;同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法。二如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作。③.还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见,如领导仍固执己见,我会毫不犹豫地再向上级领导反映。 361 | 362 | > 与上级意见不一是,你将怎么办? 363 | 364 | **回答提示:**一一般可以这样回答“我会给上级以必要的解释和提醒,在这种情况下,我会服从上级的意见。”二如果面试你的是总经理,而你所应聘的职位另有一位经理,且这位经理当时不在场,可以这样回答:“对于非原则性问题,我会服从上级的意见,对于涉及公司利益的重大问题,我希望能向更高层领导反映。” 365 | 分析:这个问题的标淮答案是思路一,如果用二的回答,必死无疑。你没有摸清楚改公司的内部情况,先想打小报告,这样的人没有人敢要。 366 | 367 | > 你工作经验欠缺,如何能胜任这项工作? 368 | 369 | **回答提示:**一如果招聘单位对应届毕业生的应聘者提出这个问题,说明招聘公司并不真正在乎“经验”,关键看应聘者怎样回答。二对这个问题的回答最好要体现出应聘者的诚垦、机智、果敢及敬业。③如“作为应届毕业生,在工作经验方面的确会有所欠缺,因此在读书期间我一直利用各种机会在这个行业里做兼职。我也发现,实际工作远比书本知识丰富、复杂。但我有较强的责任心、适应能力和学习能力,而且比较勤奋,所以在兼职中均能圆满完成各项工作,从中获取的经验也令我受益非浅。请贵公司放心,学校所学及兼职的工作经验使我一定能胜任这个职位。” 370 | 分析:这个问题思路中的答案尚可。突出自己的吃苦能力和适应性以及学习能力(不是学习成绩)为好。 371 | 372 | > 为了做好你工作份外之事,你该怎样获得他人的支持和帮助? 373 | 374 | **回答提示:**每个公司都在不断变化发展的过程中,你当然希望你的员工也是这样。你希望得到那些希望并欢迎变化的人,因为这些人明白,为了公司的发展,变化是公司日常生活中重要组成部分。这样的员工往往很容易适应公司的变化,并会对变化做出积极的响应。 375 | 376 | 377 | 378 | > 谈谈你过去做过的成功案例? 379 | 380 | **回答提示:**举一个你最有把握的例子,把来龙去脉说清楚,而不要说了很多却没有重点。切忌夸大其词,把别人的功劳到说成自己的,很多主管为了确保要用的人是最适合的,会打电话向你的前一个主管征询对你的看法及意见,所以如果说谎,是很容易穿梆的。 381 | 382 | > 谈谈你过去的工作经验中,最令你挫折的事情? 383 | 384 | **回答提示:**曾经接触过一个客户,原本就有耳闻他们以挑剔出名,所以事前的淮备功夫做得十分充分,也投入了相当多的时间与精力,最后客户虽然并没有照单全收,但是接受的程度已经出乎我们意料之外了。原以为从此可以合作愉快,却得知客户最后因为预算关系选择了另一家代理商,之前的努力因而付诸流水。尽管如此,我还是从这次的经验学到很多,如对该产业的了解,整个team的默契也更好了。 385 | 分析:借此了解你对挫折的容忍度及调解方式。 386 | 387 | > 如何安排自己的时间?会不会排斥加班? 388 | 389 | **回答提示:**基本上,如果上班工作有效率,工作量合理的话,应该不太需要加班。可是我也知道有时候很难避免加班,加上现在工作都采用责任制,所以我会调配自己的时间,全力配合。 390 | 分析:虽然不会有人心甘情愿的加班,但依旧要表现出高配合度的诚意。 391 | 392 | > 为什么我们要在众多的面试者中选择你? 393 | 394 | **回答提示:**根据我对贵公司的了解,以及我在这份工作上所累积的专业、经验及人脉,相信正是贵公司所找寻的人才。而我在工作态度、EQ上,也有圆融、成熟的一面,和主管、同事都能合作愉快。 395 | 分析:别过度吹嘘自己的能力,或信口开河地乱开支票,例如一定会为该公司带来多少钱的业务等,这样很容易给人一种爱说大话、不切实际的感觉。 396 | 397 | > 谈谈你对这个职务的期许? 398 | 399 | **回答提示:**希望能借此发挥我的所学及专长,同时也吸收贵公司在这方面的经验,就公司、我个人而言,缔造“双赢”的局面。 400 | 分析:回答前不妨先询问该公司对这项职务的责任认定及归属,因为每一家公司的状况不尽相同,以免说了一堆理想抱负却发现牛头不对马嘴。 401 | 402 | > 为什么选择这个职务? 403 | 404 | **回答提示:**这一直是我的兴趣和专长,经过这几年的磨练,也累积了一定的经验及人脉,相信我一定能胜任这个职务的。 405 | 分析:适时举出过去的“丰功伟业”,表现出你对这份职务的熟稔度,但避免过于夸张的形容或流于炫耀。 406 | 407 | > 为什么选择我们这家公司? 408 | 409 | **回答提示:**曾经在报章杂志看过关于贵公司的报道,与自己所追求的理念有志一同。而贵公司在业界的成绩也是有目共睹的,而且对员工的教育训练、升迁等也都很有制度。 410 | 分析:去面试前先做功课,了解一下该公司的背景,让对方觉得你真的很有心想得到这份工作,而不只是探探路。 411 | 412 | > 你认为你在学校属于好学生吗? 413 | 414 | **回答提示:**企业的招聘者很精明,问这个问题可以试探出很多问题:如果求职者学习成绩好,就会说:“是的,我的成绩很好,所有的成绩都很优异。当然,判断一个学生是不是好学生有很多标淮,在学校期间我认为成绩是重要的,其他方面包括思想道德、实践经验、团队精神、沟通能力也都是很重要的,我在这些方面也做得很好,应该说我是一个全面发展的学生。”如果求职者成绩不尽理想,便会说:“我认为是不是一个好学生的标淮是多元化的,我的学习成绩还可以,在其他方面我的表现也很突出,比如我去很多地方实习过,我很喜欢在快节奏和压力下工作,我在学生会组织过 ××活动,锻炼了我的团队合作精神和组织能力。” 有经验的招聘者一听就会明白,企业喜欢诚实的求职者。 415 | 416 | > 谈谈如何适应办公室工作的新环境? 417 | 418 | **回答提示:**一办公室里每个人有各自的岗位与职责,不得擅离岗位。二根据领导指示和工作安排,制定工作计划,提前预备,并按计划完成。③多请示并及时汇报,遇到不明白的要虚心请教。四抓间隙时间,多学习,努力提高自己的政治素质和业务水平。 419 | 420 | > 工作中学习到了些什么? 421 | 422 | **回答提示:**这是针对转职者提出的问题,建议此时可以配合面试工作的特点作为主要依据来回答,如业务工作需要与人沟通,便可举出之前工作与人沟通的例子,经历了哪些困难,学习到哪些经验,把握这些要点做陈述,就可以轻易过关了。 423 | 424 | > 想过创业吗? 425 | 426 | **回答提示:**这个问题可以显示你的冲劲,但如果你的回答是“有”的话,千万小心,下一个问题可能就是:那么为什么你不这样做呢? 427 | 428 | 429 | 430 | 431 | ---- 432 | 433 | 434 | 部分参考知乎,链接:https://www.zhihu.com/question/29776020/answer/45580066 -------------------------------------------------------------------------------- /interview/answers/部分面试题解答.md: -------------------------------------------------------------------------------- 1 | # 部分面试题解答(仅供参考) 2 | 3 | 这个答案不是死板的,可以结合开发案例具体讲解的。这里仅供参考。由于时间有限,不可能把每个题都写一份答案出来,希望大家多谅解。再说了,自己去找答案不是更能提高自己吗? 4 | 5 | > 什么是ANR 如何避免它? 6 | 7 | 在Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应 8 | 用程序无响应(ANR:Application Not Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR 给用户。 9 | 不同的组件发生ANR 的时间不一样,主线程(Activity、Service)是 5 秒,BroadCastReceiver 是 10 秒。 10 | 11 | **解决方案:** 12 | 将所有耗时操作,比如访问网络,Socket 通信,查询大量SQL 语句,复杂逻辑计算等都放在子线程中去,然后通过handler.sendMessage、runonUITread、AsyncTask 等方式更新UI。无论如何都要确保用户界面操作的流畅度。 13 | 如果耗时操作需要让用户等待,那么可以在界面上显示进度条。 14 | 15 | > synchronized 和volatile 关键字的区别? 16 | 17 | synchronized 和volatile的作用: 18 | 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。 19 | 2)禁止进行指令重排序。 20 | volatile 本质是在告诉jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。 21 | 区别: 22 | 1)volatile 仅能使用在变量级别;synchronized 则可以使用在变量、方法、和类级别的 23 | 2)volatile 仅能实现变量的修改可见性,并不能保证原子性;synchronized 则可以保证变量的修改可见性和原子性 24 | 3)volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。 25 | 4)volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化 26 | 27 | ---- 28 | 29 | ## 一、java部分 30 | 31 | > ##### 一、java基础面试知识点 32 | 33 | * java中==和equals和hashCode的区别 34 | 35 | ``` 36 | 参考答案: http://blog.csdn.net/tiantiandjava/article/details/46988461 37 | ``` 38 | 39 | * int、char、long各占多少字节数 40 | 41 | **答案:** 42 | 43 | 数据类型|位数|字节数 44 | -|-|- 45 | byte|8|1 46 | short|16|2 47 | int|32|4 48 | long|64|8 49 | float|32|4 50 | double|64|8 51 | char|16|2 52 | 53 | 54 | * int与integer的区别 55 | 56 | ``` 57 | 参考答案:http://www.cnblogs.com/shenliang123/archive/2011/10/27/2226903.html 58 | ``` 59 | 60 | * 探探对java多态的理解 61 | 62 | 63 | ``` 64 | Java多态性理解 65 | 66 | Java中多态性的实现 67 | 68 | 什么是多态 69 | 70 | 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。 71 | 72 | 多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用) 73 | 74 | 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实 75 | 际类型,根据其实际的类型调用其相应的方法。 76 | 77 | 多态的作用:消除类型之间的耦合关系。 78 | 79 | 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。 80 | 下面是多态存在的三个必要条件,要求大家做梦时都能背出来! 81 | 82 | 多态存在的三个必要条件 83 | 一、要有继承; 84 | 二、要有重写; 85 | 三、父类引用指向子类对象。 86 | 87 |  多态的好处: 88 | 89 | 1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。 90 | 91 | 2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。 92 | 93 | 3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。 94 | 95 | 4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。 96 | 97 | 5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。 98 | 99 | Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。 100 | ``` 101 | 102 | * String、StringBuffer、StringBuilder区别 103 | 104 | ``` 105 | String 字符串常量 106 | 107 | StringBuffer 字符串变量(线程安全) 108 | 109 | StringBuilder 字符串变量(非线程安全) 110 | 111 | 简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM 的 GC 就会开始工作,那速度是一定会相当慢的。 112 | 113 | 而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的: 114 | 115 | 116 | String S1 = "This is only a" + "simple" + " test"; 117 | StringBuffer Sb = new StringBuffer("This is only a").append("simple").append("test"); 118 | 119 | 你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个 120 |  String S1 = “This is only a” + “ simple” + “test”; 其实就是: 121 |  String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如: 122 |  String S2 = “This is only a”; 123 | String S3 = “ simple”; 124 | String S4 = “ test”; 125 | String S1 = S2 +S3 + S4; 126 | 这时候 JVM 会规规矩矩的按照原来的方式去做 127 | 128 | 在大部分情况下 StringBuffer > String 129 | 130 | StringBuffer 131 | 132 | Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。 133 | 134 | 可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。 135 | 136 | StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。 137 | 138 | 例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。 139 | 140 | 在大部分情况下 StringBuilder > StringBuffer 141 | 142 | java.lang.StringBuilder 143 | 144 | java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同 145 | ``` 146 | 147 | * 什么是内部类?内部类的作用 148 | 149 | ``` 150 | 参考答案:什么是内部类:http://www.cnblogs.com/chenssy/p/3388487.html 151 | ``` 152 | ``` 153 | 内部类的作用: 154 | 1. 内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。 155 | 2. 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。 156 | 3. 创建内部类对象的时刻并不依赖于外围类对象的创建。 157 | 4. 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。 158 | 5. 内部类提供了更好的封装,除了该外围类,其他类都不能访问 159 | ``` 160 | 161 | * 抽象类和接口区别 162 | 163 | ``` 164 | 1.默认的方法实现 165 | 抽象类可以有默认的方法实现完全是抽象的。接口根本不存在方法的实现 166 | 167 | 2.实现 168 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 169 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 170 | 171 | 3.构造器 172 | 抽象类可以有构造器 173 | 接口不能有构造器 174 | 175 | 4.与正常Java类的区别 176 | 除了你不能实例化抽象类之外,它和普通Java类没有任何区 177 | 接口是完全不同的类型 178 | 179 | 5.访问修饰符 180 | 抽象方法可以有public、protected和default这些修饰符 181 | 接口方法默认修饰符是public。你不可以使用其它修饰符。 182 | 183 | 6.main方法 184 | 抽象方法可以有main方法并且我们可以运行它 185 | 接口没有main方法,因此我们不能运行它。 186 | 187 | 7.多继承 188 | 抽象类在java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口。 189 | 190 | 8.速度 191 | 它比接口速度要快 192 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 193 | 194 | 9.添加新方法 195 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 196 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 197 | ``` 198 | 199 | * 抽象类的意义 200 | 201 | ``` 202 | 参考答案: 203 | 为其子类提供一个公共的类型 204 | 封装子类中得重复内容 205 | 定义抽象方法,子类虽然有不同的实现 但是定义是一致的 206 | ``` 207 | 208 | * 抽象类与接口的应用场景 209 | * 抽象类是否可以没有方法和属性? 210 | * 接口的意义 211 | 212 | ``` 213 | 规范、扩展、回调 214 | ``` 215 | 216 | * 泛型中extends和super的区别 217 | 218 | [参考答案:泛型中 extends 和 super 的区别?](https://itimetraveler.github.io/2016/12/27/%E3%80%90Java%E3%80%91%E6%B3%9B%E5%9E%8B%E4%B8%AD%20extends%20%E5%92%8C%20super%20%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9F/) 219 | 220 | 221 | * 父类的静态方法能否被子类重写 222 | 223 | ``` 224 | 不能 225 | ``` 226 | ``` 227 | 子类继承父类后,用相同的静态方法和非静态方法,这时非静态方法覆盖父类中的方法(即方法重写),父类的该静态方法被隐藏(如果对象是父类则调用该隐藏的方法),另外子类可继承父类的静态与非静态方法,至于方法重载我觉得它其中一要素就是在同一类中,不能说父类中的什么方法与子类里的什么方法是方法重载的体现。 228 | ``` 229 | 230 | * 进程和线程的区别 231 | 232 | ``` 233 | 简而言之,一个程序至少有一个进程,一个进程至少有一个线程。 234 | ``` 235 | ``` 236 | 线程的划分尺度小于进程,使得多线程程序的并发性高。 237 | ``` 238 | ``` 239 | 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 240 | ``` 241 | ``` 242 | 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 243 | ``` 244 | ``` 245 | 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。 246 | ``` 247 | ``` 248 | 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 249 | ``` 250 | ``` 251 | 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 252 | ``` 253 | ``` 254 | 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行. 255 | ``` 256 | ``` 257 | 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。如果有兴趣深入的话,我建议你们看看《现代操作系统》或者《操作系统的设计与实现》。对就个问题说得比较清楚。 258 | ``` 259 | 260 | * final,finally,finalize的区别 261 | * 序列化的方式 262 | * Serializable 和Parcelable 的区别 263 | * 静态属性和静态方法是否可以被继承?是否可以被重写?以及原因? 264 | * 静态内部类的设计意图 265 | * 成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用 266 | * 谈谈对kotlin的理解 267 | * 闭包和局部内部类的区别 268 | * string 转换成 integer的方式及原理 269 | 270 | ### 二、java深入源码级的面试题(有难度) 271 | 272 | * 哪些情况下的对象会被垃圾回收机制处理掉? 273 | 274 | ``` 275 | Java 垃圾回收机制最基本的做法是分代回收。内存中的区域被划分成不同的世代,对象根据其存活的时间被保存在对应世代的区域中。 276 | ``` 277 | ``` 278 | 一般的实现是划分成3个世代:年轻、年老和永久。内存的分配是发生在年轻世代中的。 279 | ``` 280 | ``` 281 | 当一个对象存活时间足够长的时候,它就会被复制到年老世代中。对于不同的世代可以使用不同的垃圾回收算法。进行世代划分的出发点是对应用中对象存活时间进行研究之后得出的统计规律。 282 | ``` 283 | ``` 284 | 一般来说,一个应用中的大部分对象的存活时间都很短。比如局部变量的存活时间就只在方法的执行过程中。基于这一点,对于年轻世代的垃圾回收算法就可以很有针对性。 285 | ``` 286 | 287 | * 讲一下常见编码方式? 288 | * utf-8编码中的中文占几个字节;int型几个字节? 289 | * 静态代理和动态代理的区别,什么场景使用? 290 | * Java的异常体系 291 | * 谈谈你对解析与分派的认识。 292 | * 修改对象A的equals方法的签名,那么使用HashMap存放这个对象实例的时候,会调用哪个equals方法? 293 | * Java中实现多态的机制是什么? 294 | * 如何将一个Java对象序列化到文件里? 295 | * 说说你对Java反射的理解 296 | * 说说你对Java注解的理解 297 | * 说说你对依赖注入的理解 298 | * 说一下泛型原理,并举例说明 299 | * Java中String的了解 300 | * String为什么要设计成不可变的? 301 | * Object类的equal和hashCode方法重写,为什么? 302 | 303 | 304 | ### 三、数据结构 305 | 306 | * 常用数据结构简介 307 | * 并发集合了解哪些? 308 | * 列举java的集合以及集合之间的继承关系 309 | 310 | ![](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/pic/collection.png?raw=true) 311 | 312 | * 集合类以及集合框架 313 | * 容器类介绍以及之间的区别(容器类估计很多人没听这个词,Java容器主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections),具体的可以看看这篇博文 [Java容器类](http://alexyyek.github.io/2015/04/06/Collection/)) 314 | 315 | ``` 316 | 参考答案: 317 | ``` 318 | 319 | ``` 320 | http://www.cnblogs.com/yuanermen/archive/2009/08/05/1539917.html 321 | ``` 322 | 323 | ``` 324 | http://alexyyek.github.io/2015/04/06/Collection/ 325 | ``` 326 | 327 | ``` 328 | http://tianmaying.com/tutorial/java_collection 329 | ``` 330 | 331 | * List,Set,Map的区别 332 | * List和Map的实现方式以及存储方式 333 | * HashMap的实现原理 334 | 335 | **(1)HashMap概述:** 336 |    HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 337 | 338 | **(2)HashMap的数据结构:** 339 | 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。 340 | 341 | ![](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/pic/hashmap.jpg?raw=true) 342 | 343 | 从上图中可以看出,HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。 344 | 345 | * HashMap数据结构? 346 | * HashMap源码理解 347 | * HashMap如何put数据(从HashMap源码角度讲解)? 348 | * HashMap怎么手写实现? 349 | * ConcurrentHashMap的实现原理 350 | * ArrayMap和HashMap的对比 351 | 352 | ``` 353 | 参考答案:http://lvable.com/?p=217 354 | ``` 355 | 356 | * HashTable实现原理 357 | * TreeMap具体实现 358 | * HashMap和HashTable的区别 359 | 360 | ``` 361 | 参考答案:http://www.233.com/ncre2/JAVA/jichu/20100717/084230917.html 362 | ``` 363 | 364 | * HashMap与HashSet的区别 365 | * HashSet与HashMap怎么判断集合元素重复? 366 | * 集合Set实现Hash怎么防止碰撞 367 | * ArrayList和LinkedList的区别,以及应用场景 368 | * 数组和链表的区别 369 | * 二叉树的深度优先遍历和广度优先遍历的具体实现 370 | * 堆的结构 371 | * 堆和树的区别 372 | * 堆和栈在内存中的区别是什么(解答提示:可以从数据结构方面以及实际实现方面两个方面去回答)? 373 | * 什么是深拷贝和浅拷贝 374 | * 手写链表逆序代码 375 | * 讲一下对树,B+树的理解 376 | * 讲一下对图的理解 377 | * 判断单链表成环与否? 378 | * 链表翻转(即:翻转一个单项链表) 379 | * 合并多个单有序链表(假设都是递增的) 380 | 381 | 382 | ### 四、线程、多线程和线程池 383 | 384 | * 开启线程的三种方式? 385 | * 线程和进程的区别? 386 | * 为什么要有线程,而不是仅仅用进程? 387 | * run()和start()方法区别 388 | * 如何控制某个方法允许并发访问线程的个数? 389 | * 在Java中wait和seelp方法的不同; 390 | * 谈谈wait/notify关键字的理解 391 | * 什么导致线程阻塞? 392 | 393 | ``` 394 | 线程的阻塞 395 | 396 | 为了解决对共享存储区的访问冲突,Java 引入了同步机制,现在让我们来考察多个线程对共享资源的访问,显然同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种情况下的访问控制问题,Java 引入了对阻塞机制的支持. 397 | 398 | 阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让我们逐一分析。 399 | 400 | 1. sleep() 方法:sleep() 允许 指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。 401 | 典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。 402 | 2. suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。典型地,suspend() 和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume() 使其恢复。 403 | 3. yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程. 404 | 4. wait() 和 notify() 方法:两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用. 405 | 406 | 初看起来它们与 suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而这一对方法则相反。 407 | 408 | 上述的核心区别导致了一系列的细节上的区别。 409 | 410 | 首先,前面叙述的所有方法都隶属于 Thread 类,但是这一对却直接隶属于 Object 类,也就是说,所有对象都拥有这一对方法。初看起来这十分不可思议,但是实际上却是很自然的,因为这一对方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用 任意对象的notify()方法则导致因调用该对象的 wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。 411 | 412 | 其次,前面叙述的所有方法都可在任何位置调用,但是这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。因此,这一对方法调用必须放置在这样的 synchronized 方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若不满足这一条件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException 异常。 413 | 414 | wait() 和 notify() 方法的上述特性决定了它们经常和synchronized 方法或块一起使用,将它们和操作系统的进程间通信机制作一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则相当于 block 和wakeup 原语(这一对方法均声明为 synchronized)。它们的结合使得我们可以实现操作系统上一系列精妙的进程间通信的算法(如信号量算法),并用于解决各种复杂的线程间通信问题。 415 | 416 | 关于 wait() 和 notify() 方法最后再说明两点: 417 | 418 | 第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。 419 | 420 | 第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。 421 | 422 | 谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend() 方法和不指定超时期限的 wait() 方法的调用都可能产生死锁。遗憾的是,Java 并不在语言级别上支持死锁的避免,我们在编程中必须小心地避免死锁。 423 | 424 | 以上我们对 Java 中实现线程阻塞的各种方法作了一番分析,我们重点分析了 wait() 和 notify() 方法,因为它们的功能最强大,使用也最灵活,但是这也导致了它们的效率较低,较容易出错。实际使用中我们应该灵活使用各种方法,以便更好地达到我们的目的。 425 | 426 | ``` 427 | 428 | * 线程如何关闭? 429 | * 讲一下java中的同步的方法 430 | * 数据一致性如何保证? 431 | * 如何保证线程安全? 432 | * 如何实现线程同步? 433 | * 两个进程同时要求写或者读,能不能实现?如何防止进程的同步? 434 | * 线程间操作List 435 | * Java中对象的生命周期 436 | * Synchronized用法 437 | * synchronize的原理 438 | * 谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解 439 | * static synchronized 方法的多线程访问和作用 440 | * 同一个类里面两个synchronized方法,两个线程同时访问的问题 441 | * volatile的原理 442 | * 谈谈volatile关键字的用法 443 | * 谈谈volatile关键字的作用 444 | * 谈谈NIO的理解 445 | * synchronized 和volatile 关键字的区别 446 | * synchronized与Lock的区别 447 | * ReentrantLock 、synchronized和volatile比较 448 | * ReentrantLock的内部实现 449 | * lock原理 450 | * 死锁的四个必要条件? 451 | * 怎么避免死锁? 452 | * 对象锁和类锁是否会互相影响? 453 | * 什么是线程池,如何使用? 454 | * Java的并发、多线程、线程模型 455 | * 谈谈对多线程的理解 456 | * 多线程有什么要注意的问题? 457 | * 谈谈你对并发编程的理解并举例说明 458 | * 谈谈你对多线程同步机制的理解? 459 | * 如何保证多线程读写文件的安全? 460 | * 多线程断点续传原理 461 | * 断点续传的实现 -------------------------------------------------------------------------------- /interview/answers/高端技术面试题参考答案和示例代码/code/BinaryTreeDemo.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/interview/answers/高端技术面试题参考答案和示例代码/code/BinaryTreeDemo.java -------------------------------------------------------------------------------- /interview/answers/高端技术面试题参考答案和示例代码/code/BubbleSortDemo.java: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 冒泡排序demo 4 | */ 5 | public class BubbleSortDemo{ 6 | 7 | /** 8 | * 冒泡排序方式1 9 | */ 10 | public void bubbleSort(int[] score){ 11 | for(int i =0;i < score.length - 1;i++) { 12 | for(int j = 0;j < score.length - 1-i;j++) { // j开始等于0 13 | if(score[j] < score[j+1]) { 14 | int temp = score[j]; 15 | score[j] = score[j+1]; 16 | score[j+1] = temp; 17 | } 18 | } 19 | } 20 | } 21 | 22 | /** 23 | * 冒泡排序方式2 24 | * 倒着遍历 25 | */ 26 | public void bubbleSort2(int[] score){ 27 | for(int i =0;i < score.length - 1;i++){ 28 | for(int j = (score.length - 2);j >= 0;j--){ 29 | if(score[j] < score[j+1]){ 30 | int temp = score[j]; 31 | score[j] = score[j+1]; 32 | score[j+1] = temp; 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /interview/answers/高端技术面试题参考答案和示例代码/code/HeapSort2Demo.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/interview/answers/高端技术面试题参考答案和示例代码/code/HeapSort2Demo.java -------------------------------------------------------------------------------- /interview/answers/高端技术面试题参考答案和示例代码/code/HeapSortDemo.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/interview/answers/高端技术面试题参考答案和示例代码/code/HeapSortDemo.java -------------------------------------------------------------------------------- /interview/answers/高端技术面试题参考答案和示例代码/code/QuickSortDemo.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/interview/answers/高端技术面试题参考答案和示例代码/code/QuickSortDemo.java -------------------------------------------------------------------------------- /interview/answers/高端技术面试题参考答案和示例代码/参考答案.md: -------------------------------------------------------------------------------- 1 | > 很多题目都是靠理解的东西,这里仅提供一个参考,具体的要结合自己项目去回答是最好的,如有差错,欢迎大家提issues。想要联系我本人,可以在我github资料上面找到联系方式。 2 | 3 | #一、图片 4 | 5 | ### 图片库的对比 6 | 7 | 图片库名称|实现原理|优点|缺点 8 | -|-|-|- 9 | Fresco||1.最大的优势便在于5.0以下(最低2.3) bitmap的加载,在5.0以下系统,Fresco将图片放到一个特别的内存区域(Ashmem),而且图片不显示时,占用的内存会自动被释放,这会使APP更加流畅,减少因图片内存占用而引发的OOM。5.0以后的系统默认存储在Ashmem区了2.支持加载Git动态图和Webp格式的图片3.图片的渐进式呈现,图片先呈现大致的轮廓,然后随着图片下载的继续,逐渐成仙清晰的图片,这对于慢网络对说,用户体验更好。|框架体积比较大,3M左右,会增加APK的大小 10 | Glide||1.图片默认格式为RGB565,而不是ARGB888,内存开销更小2.图片缓存的尺寸是和ImageView一样的,这使得图片加载更快3.支持加载Git动态图4.支持配置网络请求5.Glide的with()方法可以接收activity和fragment,图片的加载会和Activity和Fragment的生命周期保持一致|Glide 显示动画会消耗很多内存 11 | Picasso||1.图片质量高,但加载速度一般2.Picasso体积比起Glide小|只缓存一个全尺寸的图片 12 | 13 | 具体的可以参考这篇博客[Android的Glide库加载图片的用法及其与Picasso的对比](http://www.jb51.net/article/83152.htm),虽然有点老了,新版本的api有许多变动,但是还是有参考价值的。(**以后有时间我把最新的Glide 4.+ 和 Picasso最新版 Fresco 做一个对比,写一篇博客介绍一下**) 14 | 15 | ### 图片库的源码分析 16 | 17 | 这个网上有很多博客,自己可以去看看,内容太多,不方便在这里写出来了。 18 | 19 | ### 自己去实现图片库,怎么做? 20 | 21 | 这里介绍一下思路,详细的可以看我给出的一个示例sample,自己手写的一个类似于Picasso的图片框架 22 | 23 | **需要注意的几点:** 24 | 25 | * 1.首先要做好缓存,这是必备的:可以使用三级缓存,Android提供了LruCache:硬盘缓存用DiskLruCache,内存缓存用LRUCache。 26 | * 2.图片加载需要压缩,可以考虑BitmapFactory做压缩 27 | * 3.图片加载的来源,是从文件,还是网络 28 | * 4.图片的异步加载和同步加载 29 | * 30 | * 知识点内存缓存 31 | 32 | * 图片下载时请求转发 33 | 34 | 35 | #四、算法 36 | 37 | ### 排序算法有哪些? 38 | 39 | 常用的10大排序算法:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序。 40 | 41 | ### 最快的排序算法是哪个? 42 | ### 手写一个冒泡排序 43 | 44 | 见代码: 45 | 46 | ### 手写快速排序代码 47 | 48 | 见代码: 49 | 50 | ### 快速排序的过程、时间复杂度、空间复杂度 51 | ### 手写堆排序 52 | 53 | 见代码: 54 | 55 | ### 堆排序过程、时间复杂度及空间复杂度 56 | ### 写出你所知道的排序算法及时空复杂度,稳定性 57 | 58 | 一张图清楚地说明这些算法之间的对比: 59 | 60 | ![](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/pic/Sorting-algorithm.png?raw=true) 61 | 62 | 63 | 相关术语: 64 | 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面; 65 | 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面; 66 | 内排序(In-place):所有排序操作都在内存中完成; 67 | 外排序(Out-place):由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行; 68 | 时间复杂度: 一个算法执行所耗费的时间。 69 | 空间复杂度:运行完一个程序所需内存的大小 70 | 71 | 具体讲解可以参考博客:[https://www.cnblogs.com/onepixel/articles/7674659.html](https://www.cnblogs.com/onepixel/articles/7674659.html) 72 | 73 | ### 二叉树给出根节点和目标节点,找出从根节点到目标节点的路径 74 | ### 给阿里2万多名员工按年龄排序应该选择哪个算法? 75 | ### GC算法(各种算法的优缺点以及应用场景) 76 | ### 蚁群算法与蒙特卡洛算法 77 | ### 子串包含问题(KMP 算法)写代码实现 78 | ### 一个无序,不重复数组,输出N个元素,使得N个元素的和相加为M,给出时间复杂度、空间复杂度。手写算法 79 | ### 万亿级别的两个URL文件A和B,如何求出A和B的差集C(提示:Bit映射->hash分组->多文件读写效率->磁盘寻址以及应用层面对寻址的优化) 80 | ### 百度POI中如何试下查找最近的商家功能(提示:坐标镜像+R树)。 81 | ### 两个不重复的数组集合中,求共同的元素。 82 | ### 两个不重复的数组集合中,这两个集合都是海量数据,内存中放不下,怎么求共同的元素? 83 | ### 一个文件中有100万个整数,由空格分开,在程序中判断用户输入的整数是否在此文件中。说出最优的方法 84 | ### 一张Bitmap所占内存以及内存占用的计算 85 | ### 2000万个整数,找出第五十大的数字? 86 | ### 烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢? 87 | ### 求1000以内的水仙花数以及40亿以内的水仙花数 88 | ### 5枚硬币,2正3反如何划分为两堆然后通过翻转让两堆中正面向上的硬8币和反面向上的硬币个数相同 89 | ### 时针走一圈,时针分针重合几次 90 | ### N*N的方格纸,里面有多少个正方形 91 | ### x个苹果,一天只能吃一个、两个、或者三个,问多少天可以吃完? -------------------------------------------------------------------------------- /interview/contents/Android面试题.md: -------------------------------------------------------------------------------- 1 | # Android面试题 2 | 3 | Android面试题除了Android基础之外,更多的问的是一些源码级别的、原理这些等。所以想去大公司面试,一定要多看看源码和实现方式,常用框架可以试试自己能不能手写实现一下,锻炼一下自己。 4 | 5 | ### 一、Android基础知识点 6 | 7 | * 四大组件是什么 8 | * 四大组件的生命周期和简单用法 9 | * Activity之间的通信方式 10 | * Activity各种情况下的生命周期 11 | * 横竖屏切换的时候,Activity 各种情况下的生命周期 12 | * Activity与Fragment之间生命周期比较 13 | * Activity上有Dialog的时候按Home键时的生命周期 14 | * 两个Activity 之间跳转时必然会执行的是哪几个方法? 15 | * 前台切换到后台,然后再回到前台,Activity生命周期回调方法。弹出Dialog,生命值周期回调方法。 16 | * Activity的四种启动模式对比 17 | * Activity状态保存于恢复 18 | * fragment各种情况下的生命周期 19 | * Fragment状态保存startActivityForResult是哪个类的方法,在什么情况下使用? 20 | * 如何实现Fragment的滑动? 21 | * fragment之间传递数据的方式? 22 | * Activity 怎么和Service 绑定? 23 | * 怎么在Activity 中启动自己对应的Service? 24 | * service和activity怎么进行数据交互? 25 | * Service的开启方式 26 | * 请描述一下Service 的生命周期 27 | * 谈谈你对ContentProvider的理解 28 | * 说说ContentProvider、ContentResolver、ContentObserver 之间的关系 29 | * 请描述一下广播BroadcastReceiver的理解 30 | * 广播的分类 31 | * 广播使用的方式和场景 32 | * 在manifest 和代码中如何注册和使用BroadcastReceiver? 33 | * 本地广播和全局广播有什么差别? 34 | * BroadcastReceiver,LocalBroadcastReceiver 区别 35 | * AlertDialog,popupWindow,Activity区别 36 | * Application 和 Activity 的 Context 对象的区别 37 | * Android属性动画特性 38 | * 如何导入外部数据库? 39 | * LinearLayout、RelativeLayout、FrameLayout的特性及对比,并介绍使用场景。 40 | * 谈谈对接口与回调的理解 41 | * 回调的原理 42 | * 写一个回调demo 43 | * 介绍下SurfView 44 | * RecycleView的使用 45 | * 序列化的作用,以及Android两种序列化的区别 46 | * 差值器 47 | * 估值器 48 | * Android中数据存储方式 49 | 50 | ### 二、Android源码相关分析 51 | 52 | * Android动画框架实现原理 53 | * Android各个版本API的区别 54 | * Requestlayout,onlayout,onDraw,DrawChild区别与联系 55 | * invalidate和postInvalidate的区别及使用 56 | * Activity-Window-View三者的差别 57 | * 谈谈对Volley的理解 58 | * 如何优化自定义View 59 | * 低版本SDK如何实现高版本api? 60 | * 描述一次网络请求的流程 61 | * HttpUrlConnection 和 okhttp关系 62 | * Bitmap对象的理解 63 | * looper架构 64 | * ActivityThread,AMS,WMS的工作原理 65 | * 自定义View如何考虑机型适配 66 | * 自定义View的事件 67 | * AstncTask+HttpClient 与 AsyncHttpClient有什么区别? 68 | * LaunchMode应用场景 69 | * AsyncTask 如何使用? 70 | * SpareArray原理 71 | * 请介绍下ContentProvider 是如何实现数据共享的? 72 | * AndroidService与Activity之间通信的几种方式 73 | * IntentService原理及作用是什么? 74 | * 说说Activity、Intent、Service 是什么关系 75 | * ApplicationContext和ActivityContext的区别 76 | * SP是进程同步的吗?有什么方法做到同步? 77 | * 谈谈多线程在Android中的使用 78 | * 进程和 Application 的生命周期 79 | * 封装View的时候怎么知道view的大小 80 | * RecycleView原理 81 | * AndroidManifest的作用与理解 82 | 83 | ### 三、常见的一些原理性问题 84 | 85 | * Handler机制和底层实现 86 | * Handler、Thread和HandlerThread的差别 87 | * handler发消息给子线程,looper怎么启动? 88 | * 关于Handler,在任何地方new Handler 都是什么线程下? 89 | * ThreadLocal原理,实现及如何保证Local属性? 90 | * 请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系 91 | * 请描述一下View事件传递分发机制 92 | * Touch事件传递流程 93 | * 事件分发中的onTouch 和onTouchEvent 有什么区别,又该如何使用? 94 | * View和ViewGroup分别有哪些事件分发相关的回调方法 95 | * View刷新机制 96 | * View绘制流程 97 | * 自定义控件原理 98 | * 自定义View如何提供获取View属性的接口? 99 | * Android代码中实现WAP方式联网 100 | * AsyncTask机制 101 | * AsyncTask原理及不足 102 | * 如何取消AsyncTask? 103 | * 为什么不能在子线程更新UI? 104 | * ANR产生的原因是什么? 105 | * ANR定位和修正 106 | * oom是什么? 107 | * 什么情况导致oom? 108 | * 有什么解决方法可以避免OOM? 109 | * Oom 是否可以try catch?为什么? 110 | * 内存泄漏是什么? 111 | * 什么情况导致内存泄漏? 112 | * 如何防止线程的内存泄漏? 113 | * 内存泄露场的解决方法 114 | * 内存泄漏和内存溢出区别? 115 | * LruCache默认缓存大小 116 | * ContentProvider的权限管理(解答:读写分离,权限控制-精确到表级,URL控制) 117 | * 如何通过广播拦截和abort一条短信? 118 | * 广播是否可以请求网络? 119 | * 广播引起anr的时间限制是多少? 120 | * 计算一个view的嵌套层级 121 | * Activity栈 122 | * Android线程有没有上限? 123 | * 线程池有没有上限? 124 | * ListView重用的是什么? 125 | * Android为什么引入Parcelable? 126 | * 有没有尝试简化Parcelable的使用? 127 | 128 | ### 四、开发中常见的一些问题 129 | 130 | * ListView 中图片错位的问题是如何产生的? 131 | * 混合开发有了解吗? 132 | * 知道哪些混合开发的方式?说出它们的优缺点和各自使用场景?(解答:比如:RN,weex,H5,小程序,WPA等。做Android的了解一些前端js等还是很有好处的); 133 | * 屏幕适配的处理技巧都有哪些? 134 | * 服务器只提供数据接收接口,在多线程或多进程条件下,如何保证数据的有序到达? 135 | * 动态布局的理解 136 | * 怎么去除重复代码? 137 | * 画出 Android 的大体架构图 138 | * Recycleview和ListView的区别 139 | * ListView图片加载错乱的原理和解决方案 140 | * 动态权限适配方案,权限组的概念 141 | * Android系统为什么会设计ContentProvider? 142 | * 下拉状态栏是不是影响activity的生命周期 143 | * 如果在onStop的时候做了网络请求,onResume的时候怎么恢复? 144 | * Bitmap 使用时候注意什么? 145 | * Bitmap的recycler() 146 | * Android中开启摄像头的主要步骤 147 | * ViewPager使用细节,如何设置成每次只初始化当前的Fragment,其他的不初始化? 148 | * 点击事件被拦截,但是想传到下面的View,如何操作? 149 | * 微信主页面的实现方式 150 | * 微信上消息小红点的原理 151 | * CAS介绍(这是阿里巴巴的面试题,我不是很了解,可以参考博客: [CAS简介](http://blog.csdn.net/jly4758/article/details/46673835)) 152 | -------------------------------------------------------------------------------- /interview/contents/java面试题.md: -------------------------------------------------------------------------------- 1 | # java面试题汇总 2 | 3 | 熟练掌握java是很关键的,大公司不仅仅要求你会使用几个api,更多的是要你熟悉源码实现原理,甚至要你知道有哪些不足,怎么改进,还有一些java有关的一些算法,设计模式等等。 4 | 5 | ### 一、java基础面试知识点 6 | 7 | * java中==和equals和hashCode的区别 8 | * int、char、long各占多少字节数 9 | * int与integer的区别 10 | * 探探对java多态的理解 11 | * String、StringBuffer、StringBuilder区别 12 | * 什么是内部类?内部类的作用 13 | * 抽象类和接口区别 14 | * 抽象类的意义 15 | * 抽象类与接口的应用场景 16 | * 抽象类是否可以没有方法和属性? 17 | * 接口的意义 18 | * 泛型中extends和super的区别 19 | * 父类的静态方法能否被子类重写 20 | * 进程和线程的区别 21 | * final,finally,finalize的区别 22 | * 序列化的方式 23 | * Serializable 和Parcelable 的区别 24 | * 静态属性和静态方法是否可以被继承?是否可以被重写?以及原因? 25 | * 静态内部类的设计意图 26 | * 成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用 27 | * 谈谈对kotlin的理解 28 | * 闭包和局部内部类的区别 29 | * string 转换成 integer的方式及原理 30 | 31 | 32 | ### 二、java深入源码级的面试题(有难度) 33 | 34 | * 哪些情况下的对象会被垃圾回收机制处理掉? 35 | * 讲一下常见编码方式? 36 | * utf-8编码中的中文占几个字节;int型几个字节? 37 | * 静态代理和动态代理的区别,什么场景使用? 38 | * Java的异常体系 39 | * 谈谈你对解析与分派的认识。 40 | * 修改对象A的equals方法的签名,那么使用HashMap存放这个对象实例的时候,会调用哪个equals方法? 41 | * Java中实现多态的机制是什么? 42 | * 如何将一个Java对象序列化到文件里? 43 | * 说说你对Java反射的理解 44 | * 说说你对Java注解的理解 45 | * 说说你对依赖注入的理解 46 | * 说一下泛型原理,并举例说明 47 | * Java中String的了解 48 | * String为什么要设计成不可变的? 49 | * Object类的equal和hashCode方法重写,为什么? 50 | 51 | 52 | ### 三、数据结构 53 | 54 | * 常用数据结构简介 55 | * 并发集合了解哪些? 56 | * 列举java的集合以及集合之间的继承关系 57 | * 集合类以及集合框架 58 | * 容器类介绍以及之间的区别(容器类估计很多人没听这个词,Java容器主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections),具体的可以看看这篇博文 [Java容器类](http://alexyyek.github.io/2015/04/06/Collection/)) 59 | * List,Set,Map的区别 60 | * List和Map的实现方式以及存储方式 61 | * HashMap的实现原理 62 | * HashMap数据结构? 63 | * HashMap源码理解 64 | * HashMap如何put数据(从HashMap源码角度讲解)? 65 | * HashMap怎么手写实现? 66 | * ConcurrentHashMap的实现原理 67 | * ArrayMap和HashMap的对比 68 | * HashTable实现原理 69 | * TreeMap具体实现 70 | * HashMap和HashTable的区别 71 | * HashMap与HashSet的区别 72 | * HashSet与HashMap怎么判断集合元素重复? 73 | * 集合Set实现Hash怎么防止碰撞 74 | * ArrayList和LinkedList的区别,以及应用场景 75 | * 数组和链表的区别 76 | * 二叉树的深度优先遍历和广度优先遍历的具体实现 77 | * 堆的结构 78 | * 堆和树的区别 79 | * 堆和栈在内存中的区别是什么(解答提示:可以从数据结构方面以及实际实现方面两个方面去回答)? 80 | * 什么是深拷贝和浅拷贝 81 | * 手写链表逆序代码 82 | * 讲一下对树,B+树的理解 83 | * 讲一下对图的理解 84 | * 判断单链表成环与否? 85 | * 链表翻转(即:翻转一个单项链表) 86 | * 合并多个单有序链表(假设都是递增的) 87 | 88 | 89 | ### 四、线程、多线程和线程池 90 | 91 | * 开启线程的三种方式? 92 | * 线程和进程的区别? 93 | * 为什么要有线程,而不是仅仅用进程? 94 | * run()和start()方法区别 95 | * 如何控制某个方法允许并发访问线程的个数? 96 | * 在Java中wait和seelp方法的不同; 97 | * 谈谈wait/notify关键字的理解 98 | * 什么导致线程阻塞? 99 | * 线程如何关闭? 100 | * 讲一下java中的同步的方法 101 | * 数据一致性如何保证? 102 | * 如何保证线程安全? 103 | * 如何实现线程同步? 104 | * 两个进程同时要求写或者读,能不能实现?如何防止进程的同步? 105 | * 线程间操作List 106 | * Java中对象的生命周期 107 | * Synchronized用法 108 | * synchronize的原理 109 | * 谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解 110 | * static synchronized 方法的多线程访问和作用 111 | * 同一个类里面两个synchronized方法,两个线程同时访问的问题 112 | * volatile的原理 113 | * 谈谈volatile关键字的用法 114 | * 谈谈volatile关键字的作用 115 | * 谈谈NIO的理解 116 | * synchronized 和volatile 关键字的区别 117 | * synchronized与Lock的区别 118 | * ReentrantLock 、synchronized和volatile比较 119 | * ReentrantLock的内部实现 120 | * lock原理 121 | * 死锁的四个必要条件? 122 | * 怎么避免死锁? 123 | * 对象锁和类锁是否会互相影响? 124 | * 什么是线程池,如何使用? 125 | * Java的并发、多线程、线程模型 126 | * 谈谈对多线程的理解 127 | * 多线程有什么要注意的问题? 128 | * 谈谈你对并发编程的理解并举例说明 129 | * 谈谈你对多线程同步机制的理解? 130 | * 如何保证多线程读写文件的安全? 131 | * 多线程断点续传原理 132 | * 断点续传的实现 133 | 134 | 135 | 136 | ---- 137 | 138 | ### 并发编程有关知识点(这个是一般Android开发用的少的,所以建议多去看看): 139 | 140 | 平时Android开发中对并发编程可以做得比较少,Thread这个类经常会用到,但是我们想提升自己的话,一定不能停留在表面,,我们也应该去了解一下java的关于线程相关的源码级别的东西。 141 | 142 | 143 | **学习的参考资料如下:** 144 | 145 | > Java 内存模型 146 | 147 | * [java线程安全总结](http://www.iteye.com/topic/806990) 148 | * [深入理解java内存模型系列文章](http://ifeve.com/java-memory-model-0/) 149 | 150 | > 线程状态: 151 | 152 | * [一张图让你看懂JAVA线程间的状态转换](https://my.oschina.net/mingdongcheng/blog/139263) 153 | 154 | > 锁: 155 | 156 | * [锁机制:synchronized、Lock、Condition](http://blog.csdn.net/vking_wang/article/details/9952063) 157 | * [Java 中的锁](http://wiki.jikexueyuan.com/project/java-concurrent/locks-in-java.html) 158 | 159 | > 并发编程: 160 | 161 | * [Java并发编程:Thread类的使用](http://www.cnblogs.com/dolphin0520/p/3920357.html) 162 | * [Java多线程编程总结](http://blog.51cto.com/lavasoft/27069) 163 | * [Java并发编程的总结与思考](https://www.jianshu.com/p/053943a425c3#) 164 | * [Java并发编程实战-----synchronized](http://www.cnblogs.com/chenssy/p/4701027.html) 165 | * [深入分析ConcurrentHashMap](http://www.infoq.com/cn/articles/ConcurrentHashMap#) -------------------------------------------------------------------------------- /interview/contents/混合开发技术面试题.md: -------------------------------------------------------------------------------- 1 | ###### 大厂除了技术深度之外,还要求你具备一些广度的知识,比如你要会前端知识,会混合开发,至少会一种脚本语言,C C++更不用说了,也是必会的。 2 | 3 | * Hybrid做过吗? 4 | * Hybrid通信原理是什么,有做研究吗? 5 | * react native有多少了解?讲一下原理。 6 | * weex了解吗?如何自己实现类似技术? 7 | * flutter了解吗?内部是如何实现跨平台的? 8 | * Dart语言有研究贵吗? 9 | * 快应用了解吗?跟其她方式相比有什么优缺点? 10 | * 说说你用过的混合开发技术有哪些?各有什么优缺点? 11 | * 脚本语言会吗? 12 | * Python会吗? 13 | * 会不会PHP? 14 | * Gradle了解多少?groovy语法会吗? 15 | * 测试工具用过哪些? 16 | * 单元测试做过吗?如何做的? 17 | -------------------------------------------------------------------------------- /interview/contents/非技术性问题&HR问题汇总.md: -------------------------------------------------------------------------------- 1 | # 非技术性问题&HR问题汇总(待完善) 2 | 3 | 这里整理的是一些与技术没有直接关系的面试题,但是能够考察你的综合水平,所以不要以为不是技术问题,就不看,往往有时候就是这样一些细节的题目被忽视,而错过了一次次面试机会。 4 | 5 | ---- 6 | 7 | > ## 非技术问题 8 | 9 | * 介绍你做过的哪些项目 10 | * 都使用过哪些框架、平台? 11 | * 都使用过哪些自定义控件? 12 | * 研究比较深入的领域有哪些? 13 | * 除了简历上的工作经历,您还会去关注哪些领域? 14 | * 对业内信息的关注渠道有哪些? 15 | * 最近都读哪些书? 16 | * 有没有什么开源项目? 17 | * 自己最擅长的技术点,最感兴趣的技术领域和技术点 18 | * 项目中用了哪些开源库,如何避免因为引入开源库而导致的安全性和稳定性问题 19 | * 实习过程中做了什么,有什么产出? 20 | 21 | ---- 22 | 23 | > ## HR提出的面试问题 24 | 25 | ### (一)关于实习的面试题(仅供参考,也欢迎大家补充) 26 | 27 | * 公司实习最大的收获是什么? 28 | * 实习过程中周围同事/同学有哪些值得学习的地方? 29 | * 是否可以实习,可以实习多久? 30 | * 你的学习方法是什么样的?实习过程中如何学习?实习项目中遇到的最大困难是什么以及如何解决的? 31 | * 其他同学都投了哪些公司? 32 | 33 | ### (二)对于有工作经验的求职者的面试题目 34 | 35 | **主要从以下几个方面考查大家的综合素质:** 36 | 37 | 38 | ##### (1)个人的基本了解,自我介绍,优缺点,学历,工作地,教育背景等 39 | 40 | * 评价下自己,评价下自己的技术水平,个人代码量如何? 41 | * 你朋友对你的评价? 42 | * 自己的优点和缺点是什么?并举例说明? 43 | * 你觉得你个性上最大的优点是什么? 44 | * 说说你最大的缺点? 45 | * 最能概括你自己的三个词是什么? 46 | * 何时可以到职? 47 | * 你并非毕业于名牌院校? 48 | * 说说你的家庭? 49 | * 除了本公司外,还应聘了哪些公司?(类似问题:当前的offer状况) 50 | * 通过哪些渠道了解的招聘信息? 51 | * 你的业余爱好是什么? 52 | * 你做过的哪件事最令自己感到骄傲? 53 | 54 | ##### (2)灵活应变能力(也涉及工作态度) 55 | 56 | * 为什么要离职? 57 | * 您在前一家公司的离职原因是什么?(您为何要离开目前服务的这家公司?) 58 | * 谈谈你对跳槽的看法? 59 | * 怎样看待学历和能力? 60 | * 你有哪些要问我的? 61 | * 您跟您的主管或直接上司有没有针对以上离职原因的这些问题沟通过?如果没有请说明原因。如果有请说一下过程和结果? 62 | * 您觉得你关注的这些领域跟您目前从事的职业有哪些利弊关系?如果有请说明利弊关系。 63 | * 您不觉得您的知识结构有些狭窄或兴趣比较贫乏,说说未来改善的计划? 64 | * 您在选择工作中更看重的是什么?(可能是成长空间、培训机会、发挥平台、薪酬等答案) 65 | * 您可不可以说说您在薪酬方面的心里预期?(如果问题6的回答中薪酬不是排在第一,这个问题基本会被问到) 66 | * 那您刚才的意思也可以理解为:薪酬方面可以适当降低于您的心里预期,对吗?(这是针对问题7的回答继续提问的,问这个问题说明求职者给出的薪酬可以综合考虑,有让步空间) 67 | * 有人说挣未来比挣钱更为重要,您怎么理解?(这是针对问题7的回答继续提问的,问这个问题说明求职者针对薪酬这个问题不肯让步) 68 | * 有人说挣未来比挣钱更为重要,您怎么理解?(如果问题6的回答的答案中,薪酬排在第一,一般会被问这个问题) 69 | * 假设,某一天,在工作办公室走廊,您和一位同事正在抱怨上级陈某平时做事缺乏公平性,恰巧被陈某听到,您会怎么办? 70 | * 您怎么看待加班问题? 71 | * 怎么样处理工作和生活的关系?怎么处理在工作中遇到困难?请举例说明 72 | 73 | ##### (3)社交能力和人际关系 74 | * 1.在您的现实生活中,您最不喜欢和什么样的人共事?为什么?举例说明。 75 | * 2.在您认识的人中,有没有人不喜欢您?为什么不喜欢您?请举例说明。 76 | * 3.当老板/上司/同事/客户误会你,你会怎么办? 77 | * 4.当你发现其他部门的工作疏漏已经影响到您的工作绩效时,您怎么办? 78 | * 5.您希望在什么样的领导下工作? 79 | 80 | ##### (4)判断力,情绪控制力(压力承受力) 81 | * 1.我们工作与生活历程并不是一帆风顺的,谈谈您的工作或生活中出现的挫折或低潮期,您如何克服? 82 | * 2.假如您的上司是一个非常严厉、领导手腕强硬,时常给您巨大压力的人,您觉得这种领导方式对您有何利、弊? 83 | * 3.您的领导给您布置了一项您以前从未触及过的任务,您打算如何去完成它?(如果有类似的经历说说完成的经历。) 84 | * 4.谈谈您以往职业生涯中最有压力的一、两件事,并说说是如何克服的。 85 | * 5.谈谈您以往职业生涯中令您有成就感的一、两件事,并说说它给您的启示。 86 | * 6.讲一件你印象最深的一件事情 87 | * 7.介绍一个你影响最深的项目 88 | 89 | ##### (5)行动与协调能力、沟通能力 90 | * 1.您觉得自己的个性适合井然有序的工作环境还是灵活自如的工作环境。 91 | * 2.请您举一个例子,说明在完成一项重要任务时,您是怎样和他人进行有效合作的。 92 | * 3.请描述当你意识到工作进程中出现问题了,你是如何处理的? 93 | * 4.请说出一个工作进程中的确切目标,你怎样确保达到此既定目标。 94 | * 5.请您举一个例子,说明在完成一项重要任务时,您是怎样和他人进行有效合作的。 95 | * 6.当你要牺牲自己的某些方面与他人共事时,你会怎么办? 96 | * 7.有时团队成员不能有效共事,当遇到这种问题时你是怎么处理的?你又是如何改善这类情况的? 97 | * 8.我们有时不得不与自己不喜欢的人在一个团队工作,如果遇到这样的情况你会怎么办? 98 | 99 | ##### (6)责任心、纪律性及归属感 100 | * 1.您对委任的任务完成不了时如何处理? 101 | * 2.请描述一下您以往所就职公司中您认为最适合您自己的企业文化的特色 102 | * 3.描述一下您对上司所布置任务的完成思想与过程。 103 | * 4.当您所在的集体处于竞争劣势时,您有什么想法和行动? 104 | * 5.往往跨组织的任务中,由于涉及过多成员最后易形成责任者缺位现象,您如果身处其境会是什么心态? 105 | * 6.您每一次离职时有没有过失落感?您跟过去就职过的公司的一、两个上司或同事还有联系吗?并说说他们目前的处境。 106 | 107 | ##### (7)管理能力(面试管理岗会被问到) 108 | * 1.您的下属未按期完成您所布置给他的任务,如果您的上司责怪下来,您认为这是谁的责任,为什么? 109 | * 2.在您以往的工作中是如何去约束部属的,是如何去调动他们积极性的? 110 | * 3.举个例子来说明一下您曾经做过的一个成功计划及实施过程。工作中您发现自己的实施结果与事先计划出现较大的偏差,你将如何去行动? 111 | * 4.说说您对下属布置的任务在时间方面是如何要求的? 112 | * 5.说说您在完成上司布置的任务时,在时间方面是如何要求自己的? 113 | * 6.您以往在领导岗位中,一个月内分别有哪些主要的工作任务? 114 | * 7.当您发现您的部属目前士气较低沉,您一般从哪些方面去调动? 115 | * 8.说说您在以往领导岗位中出现管理失控的事例及事后的原因分析。您的部属在一个专业的问题上跟您发生争议,您如何对待这种事件? 116 | 117 | ---- 118 | 部分问题来源于知乎,链接:https://www.zhihu.com/question/29776020/answer/45580066 -------------------------------------------------------------------------------- /interview/contents/高端技术面试题.md: -------------------------------------------------------------------------------- 1 | # 高端技术面试题 2 | 3 | 4 | **这里讲的是大公司需要用到的一些高端Android技术,这里专门整理了一个文档,希望大家都可以看看。这些题目有点技术含量,需要好点时间去研究一下的。** 5 | 6 | ### 一、图片 7 | 8 | * 图片库对比 9 | * 图片库的源码分析 10 | * 图片框架缓存实现 11 | * LRUCache原理 12 | * 图片加载原理 13 | * 自己去实现图片库,怎么做? 14 | * Glide源码解析 15 | * Glide使用什么缓存? 16 | * Glide内存缓存如何控制大小? 17 | 18 | ### 二、网络和安全机制 19 | 20 | * 网络框架对比和源码分析 21 | * 自己去设计网络请求框架,怎么做? 22 | * okhttp源码 23 | * 网络请求缓存处理,okhttp如何处理网络缓存的 24 | * 从网络加载一个10M的图片,说下注意事项 25 | * TCP的3次握手和四次挥手 26 | * TCP与UDP的区别 27 | * TCP与UDP的应用 28 | * HTTP协议 29 | * HTTP1.0与2.0的区别 30 | * HTTP报文结构 31 | * HTTP与HTTPS的区别以及如何实现安全性 32 | * 如何验证证书的合法性? 33 | * https中哪里用了对称加密,哪里用了非对称加密,对加密算法(如RSA)等是否有了解? 34 | * client如何确定自己发送的消息被server收到? 35 | * 谈谈你对WebSocket的理解 36 | * WebSocket与socket的区别 37 | * 谈谈你对安卓签名的理解。 38 | * 请解释安卓为啥要加签名机制? 39 | * 视频加密传输 40 | * App 是如何沙箱化,为什么要这么做? 41 | * 权限管理系统(底层的权限是如何进行 grant 的)? 42 | 43 | 44 | ### 三、数据库 45 | 46 | * sqlite升级,增加字段的语句 47 | * 数据库框架对比和源码分析 48 | * 数据库的优化 49 | * 数据库数据迁移问题 50 | 51 | ### 四、算法 52 | 53 | * 排序算法有哪些? 54 | * 最快的排序算法是哪个? 55 | * 手写一个冒泡排序 56 | * 手写快速排序代码 57 | * 快速排序的过程、时间复杂度、空间复杂度 58 | * 手写堆排序 59 | * 堆排序过程、时间复杂度及空间复杂度 60 | * 写出你所知道的排序算法及时空复杂度,稳定性 61 | * 二叉树给出根节点和目标节点,找出从根节点到目标节点的路径 62 | * 给阿里2万多名员工按年龄排序应该选择哪个算法? 63 | * GC算法(各种算法的优缺点以及应用场景) 64 | * 蚁群算法与蒙特卡洛算法 65 | * 子串包含问题(KMP 算法)写代码实现 66 | * 一个无序,不重复数组,输出N个元素,使得N个元素的和相加为M,给出时间复杂度、空间复杂度。手写算法 67 | * 万亿级别的两个URL文件A和B,如何求出A和B的差集C(提示:Bit映射->hash分组->多文件读写效率->磁盘寻址以及应用层面对寻址的优化) 68 | * 百度POI中如何试下查找最近的商家功能(提示:坐标镜像+R树)。 69 | * 两个不重复的数组集合中,求共同的元素。 70 | * 两个不重复的数组集合中,这两个集合都是海量数据,内存中放不下,怎么求共同的元素? 71 | * 一个文件中有100万个整数,由空格分开,在程序中判断用户输入的整数是否在此文件中。说出最优的方法 72 | * 一张Bitmap所占内存以及内存占用的计算 73 | * 2000万个整数,找出第五十大的数字? 74 | * 烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢? 75 | * 求1000以内的水仙花数以及40亿以内的水仙花数 76 | * 5枚硬币,2正3反如何划分为两堆然后通过翻转让两堆中正面向上的硬8币和反面向上的硬币个数相同 77 | * 时针走一圈,时针分针重合几次 78 | * N*N的方格纸,里面有多少个正方形 79 | * x个苹果,一天只能吃一个、两个、或者三个,问多少天可以吃完? 80 | 81 | ### 五、插件化、模块化、组件化、热修复、增量更新、Gradle 82 | 83 | * 对热修复和插件化的理解 84 | * 插件化原理分析 85 | * 模块化实现(好处,原因) 86 | * 热修复,插件化 87 | * 项目组件化的理解 88 | * 描述清点击 Android Studio 的 build 按钮后发生了什么 89 | 90 | ### 六、架构设计和设计模式 91 | 92 | * 谈谈你对Android设计模式的理解 93 | * MVC MVP MVVM原理和区别 94 | * 你所知道的设计模式有哪些? 95 | * 项目中常用的设计模式 96 | * 手写生产者/消费者模式 97 | * 写出观察者模式的代码 98 | * 适配器模式,装饰者模式,外观模式的异同? 99 | * 用到的一些开源框架,介绍一个看过源码的,内部实现过程。 100 | * 谈谈对RxJava的理解 101 | * RxJava的功能与原理实现 102 | * RxJava的作用,与平时使用的异步操作来比的优缺点 103 | * 说说EventBus作用,实现方式,代替EventBus的方式 104 | * 从0设计一款App整体架构,如何去做? 105 | * 说一款你认为当前比较火的应用并设计(比如:直播APP,P2P金融,小视频等) 106 | * 谈谈对java状态机理解 107 | * Fragment如果在Adapter中使用应该如何解耦? 108 | * Binder机制及底层实现 109 | * 对于应用更新这块是如何做的?(解答:灰度,强制更新,分区域更新)? 110 | * 实现一个Json解析器(可以通过正则提高速度) 111 | * 统计启动时长,标准 112 | 113 | ### 七、性能优化 114 | 115 | * 如何对Android 应用进行性能分析以及优化? 116 | * ddms 和 traceView 117 | * 性能优化如何分析systrace? 118 | * 用IDE如何分析内存泄漏? 119 | * Java多线程引发的性能问题,怎么解决? 120 | * 启动页白屏及黑屏解决? 121 | * 启动太慢怎么解决? 122 | * 怎么保证应用启动不卡顿? 123 | * App启动崩溃异常捕捉 124 | * 自定义View注意事项 125 | * 现在下载速度很慢,试从网络协议的角度分析原因,并优化(提示:网络的5层都可以涉及)。 126 | * Https请求慢的解决办法(提示:DNS,携带数据,直接访问IP) 127 | * 如何保持应用的稳定性 128 | * RecyclerView和ListView的性能对比 129 | * ListView的优化 130 | * RecycleView优化 131 | * View渲染 132 | * Bitmap如何处理大图,如一张30M的大图,如何预防OOM 133 | * java中的四种引用的区别以及使用场景 134 | * 强引用置为null,会不会被回收? 135 | 136 | ### 八、NDK、jni、Binder、AIDL、进程通信有关 137 | 138 | * 请介绍一下NDK 139 | * 什么是NDK库? 140 | * jni用过吗? 141 | * 如何在jni中注册native函数,有几种注册方式? 142 | * Java如何调用c、c++语言? 143 | * jni如何调用java层代码? 144 | * 进程间通信的方式? 145 | * Binder机制 146 | * 简述IPC? 147 | * 什么是AIDL? 148 | * AIDL解决了什么问题? 149 | * AIDL如何使用? 150 | * Android 上的 Inter-Process-Communication 跨进程通信时如何工作的? 151 | * 多进程场景遇见过么? 152 | * Android进程分类? 153 | * 进程和 Application 的生命周期? 154 | * 进程调度 155 | * 谈谈对进程共享和线程安全的认识 156 | * 谈谈对多进程开发的理解以及多进程应用场景 157 | * 什么是协程? 158 | 159 | ### 九、framework层、ROM定制、Ubuntu、Linux之类的问题 160 | 161 | * java虚拟机的特性 162 | * 谈谈对jvm的理解 163 | * JVM内存区域,开线程影响哪块内存 164 | * 对Dalvik、ART虚拟机有什么了解? 165 | * Art和Dalvik对比 166 | * 虚拟机原理,如何自己设计一个虚拟机(内存管理,类加载,双亲委派) 167 | * 谈谈你对双亲委派模型理解 168 | * JVM内存模型,内存区域 169 | * 类加载机制 170 | * 谈谈对ClassLoader(类加载器)的理解 171 | * 谈谈对动态加载(OSGI)的理解 172 | * 内存对象的循环引用及避免 173 | * 内存回收机制、GC回收策略、GC原理时机以及GC对象 174 | * 垃圾回收机制与调用System.gc()区别 175 | * Ubuntu编译安卓系统 176 | * 系统启动流程是什么?(提示:Zygote进程 –> SystemServer进程 –> 各种系统服务 –> 应用进程) 177 | * 大体说清一个应用程序安装到手机上时发生了什么 178 | * 简述Activity启动全部过程 179 | * App启动流程,从点击桌面开始 180 | * 逻辑地址与物理地址,为什么使用逻辑地址? 181 | * Android为每个应用程序分配的内存大小是多少? 182 | * Android中进程内存的分配,能不能自己分配定额内存? 183 | * 进程保活的方式 184 | * 如何保证一个后台服务不被杀死?(相同问题:如何保证service在后台不被kill?)比较省电的方式是什么? 185 | * App中唤醒其他进程的实现方式 -------------------------------------------------------------------------------- /interview/summary.md: -------------------------------------------------------------------------------- 1 | # 国内一线互联网公司面试题汇总 2 | 3 | ---- 4 | 5 | 这些题目是网友去百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。 6 | 7 | 熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。 8 | 9 | 欢迎一线公司员工以及网友提交面试题库,欢迎star。 10 | 11 | 网上的都是按照公司划分的,想找具体某一方面的知识点有点不好找,我这里就根据知识点分门别类的整理了一下,想看哪一块可以快速找到。 12 | 13 | ### 主要分为以下几部分: 14 | 15 | > ### (一)[java面试题](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/contents/java%E9%9D%A2%E8%AF%95%E9%A2%98.md) 16 | 17 | >**(1)java基础面试知识点** 18 | > 19 | >**(2)java深入源码级的面试题(有难度)** 20 | > 21 | >**(3)数据结构** 22 | > 23 | >**(4)线程、多线程和线程池** 24 | > 25 | >**(5)并发编程有关知识点(这个是一般Android开发用的少的,所以建议多去看看):** 26 | 27 | > ### (二)[Android面试题](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/contents/Android%E9%9D%A2%E8%AF%95%E9%A2%98.md) 28 | 29 | >**(1)Android基础知识点** 30 | > 31 | >**(2)Android源码相关分析** 32 | > 33 | >**(3)常见的一些原理性问题** 34 | > 35 | >**(4)开发中常见的一些问题** 36 | 37 | > ### (三)[混合开发技术面试题](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/contents/%E6%B7%B7%E5%90%88%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF%E9%9D%A2%E8%AF%95%E9%A2%98.md) 38 | 39 | > ### (四)[高端技术面试题](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/contents/%E9%AB%98%E7%AB%AF%E6%8A%80%E6%9C%AF%E9%9D%A2%E8%AF%95%E9%A2%98.md) 40 | 41 | >**(1)图片** 42 | > 43 | >**(2)网络和安全机制** 44 | > 45 | >**(3)数据库** 46 | > 47 | >**(4)算法** 48 | > 49 | >**(5)插件化、模块化、组件化、热修复、增量更新、Gradle** 50 | > 51 | >**(6)架构设计和设计模式** 52 | > 53 | >**(7)性能优化** 54 | > 55 | >**(8)NDK、jni、Binder、AIDL、进程通信有关** 56 | > 57 | >**(9)framework层、ROM定制、Ubuntu、Linux之类的问题** 58 | > 59 | > ### (五)[非技术性问题&HR问题汇总](https://github.com/AweiLoveAndroid/CommonDevKnowledge/blob/master/interview/contents/%E9%9D%9E%E6%8A%80%E6%9C%AF%E6%80%A7%E9%97%AE%E9%A2%98%26HR%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB.md) 60 | 61 | >**(1)非技术问题** 62 | > 63 | >**(2)HR提出的面试问题** 64 | 65 | > ### (六)[部分面试题解答](https://github.com/AweiLoveAndroid/CommonDevKnowledge/tree/master/interview/answers) 66 | 67 | ---- 68 | 69 | ### 鸣谢 70 | 71 | [阿里、腾讯、百度、华为、京东、搜狗和滴滴最新面试题汇集](https://mp.weixin.qq.com/s?__biz=MzIyMjQ0MTU0NA==&mid=2247484617&idx=1&sn=3734e643d241ac9615424dd44462ee2d&chksm=e82c3deedf5bb4f82e7be0823739774a0a2cf8372284c8409471c2752fea1f367ca3f6857795&mpshare=1&scene=23&srcid=1128DKotEvTe4dheaTextbqp#rd) 72 | 73 | [2017下半年,一二线互联网公司Android面试题汇总](https://zhuanlan.zhihu.com/p/30016683) 74 | 75 | [2017 年初、阿里、腾讯、百度、华为、京东、搜狗和滴滴面试题汇集(更新篇)](https://zhuanlan.zhihu.com/p/26327485) 76 | 77 | [android_interview](https://github.com/LRH1993/android_interview) 78 | 79 | [AndroidInterview-Q-A](https://github.com/JackyAndroid/AndroidInterview-Q-A) 80 | 81 | 82 | ---- 83 | ### 这份面试题整理会持续更新,欢迎`star` 和 `fork`,不过仍有更多内容尚未完善,欢迎大家投稿。 84 | -------------------------------------------------------------------------------- /pic/Sorting-algorithm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/Sorting-algorithm.png -------------------------------------------------------------------------------- /pic/architucture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/architucture.png -------------------------------------------------------------------------------- /pic/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/collection.png -------------------------------------------------------------------------------- /pic/donation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/donation.png -------------------------------------------------------------------------------- /pic/hashmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/hashmap.jpg -------------------------------------------------------------------------------- /pic/http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/http.png -------------------------------------------------------------------------------- /pic/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AweiLoveAndroid/CommonDevKnowledge/9fa7eaae902caa07e374b749cd9176a9b7b9a87f/pic/logo.png -------------------------------------------------------------------------------- /双击back退出app/双击back退出app.md: -------------------------------------------------------------------------------- 1 | # 双击back返回键退出app功能的实现方式 2 | 3 | 有两种实现思路,看个人喜好吧: 4 | 5 | ### 方式1: 6 | 7 | 8 | public class MainActivity extends Activity { 9 | 10 | private Toast toast; 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_main); 16 | toast = Toast.makeText(getApplicationContext(), "确定退出?", 0); 17 | } 18 | 19 | public void onBackPressed() { 20 | quitToast(); 21 | } 22 | 23 | private void quitToast() { 24 | if(null == toast.getView().getParent()) { 25 | toast.show(); 26 | }else{ 27 | System.exit(0); 28 | } 29 | } 30 | } 31 | 32 | 33 | ### 方式2: 34 | 35 | public class MainActivity extends Activity { 36 | 37 | private Toast toast; 38 | rotected void onCreate(Bundle savedInstanceState) { 39 | ... 40 | toast = Toast.makeText(this, "再按一次退出应用", Toast.LENGTH_SHORT); 41 | toast.setGravity(Gravity.BOTTOM, 0, ConversionUtil.dip2px(this, 150)); 42 | } 43 | 44 | @Override 45 | public void onBackPressed() { 46 | if (doubleBackToExitPressedOnce) { 47 | if(toast!=null){ 48 | toast.cancel(); 49 | } 50 | super.onBackPressed(); 51 | return; 52 | } 53 | 54 | this.doubleBackToExitPressedOnce = true; 55 | toast.show(); 56 | 57 | new Handler().postDelayed(new Runnable() { 58 | 59 | @Override 60 | public void run() { 61 | doubleBackToExitPressedOnce=false; 62 | } 63 | }, 2000); 64 | } 65 | } -------------------------------------------------------------------------------- /国内BATH等大厂开源的安卓有关的库/全面总结国内BATH等大厂开源的安卓有关的库.md: -------------------------------------------------------------------------------- 1 | 安卓开发一直在用大公司的开源库,下面来整理一下与安卓开发有关的库。 2 | 3 | ## 一、阿里巴巴 4 | 5 | #### (一)UI有关 6 | 7 | >**1. 多页面切换场景统一解决方案 UltraViewPager** 8 | 9 | UltraViewPager 是阿里开源的一个封装多种特性的 ViewPager ,主要是为多页面切换场景提供统一解决方案。 10 | 11 | 12 |  **主要功能:** 13 | 14 | 1. 支持横向滑动/纵向滑动 15 | 2. 支持一屏内显示多页 16 | 3. 支持循环滚动 17 | 4. 支持定时滚动,计时器使用 Handler 实现 18 | 5. 支持设置 ViewPager 的最大宽高 19 | 6. setRatio 按比例显示 UltraviewPager 20 | 7. 内置 indicator ,只需简单设置几个属性就可以完成展示,支持圆点和 Icon; 21 | 8. 内置两种页面切换动效 22 | 23 | ![](http://upload-images.jianshu.io/upload_images/6098829-c1cb507561b27194.gif?imageMogr2/auto-orient/strip) 24 | ![](http://upload-images.jianshu.io/upload_images/6098829-6b7d230b704c54d5.gif?imageMogr2/auto-orient/strip) ![](http://upload-images.jianshu.io/upload_images/6098829-d91deba23f66db91.gif?imageMogr2/auto-orient/strip) 25 | 26 | >**2.vlayout** 27 |   vlayout是一个针对`RecyclerView`的LayoutManager扩展, 主要提供一整套布局方案和布局间的组件复用的问题。 28 | 29 | 默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等。 30 | 31 | LinearLayoutHelper: 线性布局 32 | GridLayoutHelper: Grid布局, 支持横向的colspan 33 | FixLayoutHelper: 固定布局,始终在屏幕固定位置显示 34 | ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等 35 | FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置 36 | ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值 37 | SingleLayoutHelper: 通栏布局,只会显示一个组件View 38 | OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素 39 | StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底 40 | StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度 41 | 42 | [github地址:vlayout](https://github.com/alibaba/vlayout) 43 | 44 | 45 | #### (二)框架有关 46 | 47 | >**1. Android 应用热修复工具 AndFix** 48 | 49 |   AndFix 是阿里巴巴开源的 Android 应用热修复工具,帮助 Anroid 开发者修复应用的线上问题。Andfix 是 "**And**roid hot-**fix**" 的缩写。 50 |   AndFix 支持 Android 2.3 - 6.0,ARM 和 x86 架构,dalvik 运行时和 art 运行时。AndFix 的分支是 .apatch 文件。 51 | 52 |  **(一)AndFix 方法体取代实现规则:** 53 | 54 | ![](http://upload-images.jianshu.io/upload_images/6098829-74264ec1266edc8c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 55 | 56 |  **(二)Bug 修复过程:** 57 | 58 | ![](http://upload-images.jianshu.io/upload_images/6098829-3f3de970008eba66.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 59 | 60 |  **(三)使用** 61 | 62 |   1. 生成 .apatch 文件: 63 | 64 | usage: apkpatch -f -t -o -k -p <***> -a -e <***> 65 | -a,--alias alias. 66 | -e,--epassword <***> entry password. 67 | -f,--from new Apk file path. 68 | -k,--keystore keystore path. 69 | -n,--name patch name. 70 | -o,--out output dir. 71 | -p,--kpassword <***> keystore password. 72 | -t,--to old Apk file path. 73 | 74 |   2.合并 .apatch 文件: 75 | 76 | usage: apkpatch -m -k -p <***> -a -e <***> 77 | -a,--alias alias. 78 | -e,--epassword <***> entry password. 79 | -k,--keystore keystore path. 80 | -m,--merge path of .apatch files. 81 | -n,--name patch name. 82 | -o,--out output dir. 83 | -p,--kpassword <***> keystore password. 84 | 85 | >**2. 非侵入式运行期 AOP 框架 Dexposed** 86 | 87 |   Dexposed 是阿里巴巴无线事业部第一个重量级 Andorid 开源软件,基于 ROOT 社区著名开源项目 Xposed 改造剥离了 ROOT 部分,演化为服务于所在应用自身的 AOP 框架。它支撑了阿里大部分 App 的在线分钟级客户端 bugfix 和线上调试能力。 88 |   Dexposed 的 AOP 是实现了纯非侵入式,没有任何注释处理器,weaver 或者字节码重写程序。Dexposed 的集成非常简单,就像加载一个 JNI 库一样,只需要在初始化的时候插入一行代码。 89 | 90 | **经典用例** 91 | 92 | 1.典型的 AOP 编程 93 | 2.仪表化 (测试,性能监控等等) 94 | 3.在线热修复(重要,关键,安全漏洞等等) 95 | 4.SDK hooking,更好的开发体验 96 | 97 | **大致用法:** 98 | 99 | 1.Gradle 依赖: 100 | 101 | native_dependencies { 102 | artifact 'com.taobao.dexposed:dexposed_l:0.2+:armeabi' 103 | artifact 'com.taobao.dexposed:dexposed:0.2+:armeabi' 104 | } 105 | dependencies { 106 | compile files('libs/dexposedbridge.jar') 107 | } 108 | 109 | 2.初始化: 110 | 111 | public class MyApplication extends Application { 112 | @Override public void onCreate() { 113 | // Check whether current device is supported (also initialize Dexposed framework if not yet) 114 | if (DexposedBridge.canDexposed(this)) { 115 | // Use Dexposed to kick off AOP stuffs. 116 | ... 117 | } 118 | } 119 | ... 120 | } 121 | 122 | **基础使用示例代码1:** 123 | 124 | // Target class, method with parameter types, followed by the hook callback (XC_MethodHook). 125 | DexposedBridge.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodHook() { 126 | 127 | // To be invoked before Activity.onCreate(). 128 | @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 129 | // "thisObject" keeps the reference to the instance of target class. 130 | Activity instance = (Activity) param.thisObject; 131 | 132 | // The array args include all the parameters. 133 | Bundle bundle = (Bundle) param.args[0]; 134 | Intent intent = new Intent(); 135 | // XposedHelpers provide useful utility methods. 136 | XposedHelpers.setObjectField(param.thisObject, "mIntent", intent); 137 | 138 | // Calling setResult() will bypass the original method body use the result as method return value directly. 139 | if (bundle.containsKey("return")) 140 | param.setResult(null); 141 | } 142 | 143 | // To be invoked after Activity.onCreate() 144 | @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { 145 | XposedHelpers.callMethod(param.thisObject, "sampleMethod", 2); 146 | } 147 | }); 148 | 149 | **基础使用示例代码2:** 150 | 151 | DexposedBridge.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodReplacement() { 152 | 153 | @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { 154 | // Re-writing the method logic outside the original method context is a bit tricky but still viable. 155 | ... 156 | } 157 | 158 | }); 159 | 160 | 161 | >**3. Android 容器化框架 Atlas** 162 | 163 |   Atlas 是由阿里巴巴移动团队自研的手机淘宝安卓客户端容器化框架,以容器化思路解决大规模团队协作问题,实现并行开发、快速迭代和动态部署,适用于 Android 4.x 以上系统版本的大小型 App 开发。 164 | 165 |   Atlas 适用于大规模团队的协同开发。通过提供组件化、动态性、解耦化的支持,能够实现每个业务在开发阶段独立编译、独立调试、独立运行,最后再以一个组件的形式集成到客户端中,每个业务之间并行开发互不影响。此外,还具备客户端动态发版和快速修复的能力。 166 | 167 | **特性:** 168 | 169 | 1. 在工程期,实现工程独立开发,调试的功能,工程模块可以独立。 170 | 2. 在运行期,实现完整的组件生命周期的映射,类隔离等机制。 171 | 3. 在运维期,提供快速增量的更新修复能力,快速升级。 172 | 173 | >**4. ARouter** 174 |   一个安卓路由器中间件,帮助应用程序导航到活动和自定义服务。`组件化开发`可以用到它。 175 | 176 | [github地址:ARouter](https://github.com/alibaba/ARouter) 177 | 178 | #### (三)跨平台框架有关 179 | 180 | >**1.weex** 181 |   跨平台的UI框架 182 | 183 | [github地址: weex](https://github.com/apache/incubator-weex) 184 | [weex的文档](https://github.com/alibaba/weex/wiki/Weex-Community) 185 | [weex官网](https://weex.apache.org/) 186 | 187 | >**2.Tangram-Android** 188 |   Tangram是一套动态化构建 Native 页面的框架,它包含 Tangram Android、Tangram iOS,管理后台等一些列基础设施。本工程是 Tangram Android 的sdk 项目地址,底层依赖于 [vlayout](https://github.com/alibaba/vlayout) 和 [UltraViewPager](https://github.com/alibaba/UltraViewPager)。 189 | 190 | 特点: 191 | 192 | 1.Android iOS 双平台支持,iOS 版本参考开源库 [Tangram-iOS](https://github.com/alibaba/Tangram-iOS)。 193 | 2.通过 json 创建页面视图,并提供了默认的解析器。 194 | 3.可轻松实现页面视图的回收与复用。 195 | 4.框架提供多种默认的布局方式。 196 | 5.通过 json 数据或代码支持自定义布局样式。 197 | 6.高性能,基于 [vlayout](https://github.com/alibaba/vlayout) 198 | 7.支持扩展功能模块 199 | 200 | > **3.LuaViewSDK** 201 | 202 | **(1) LuaViewSDK简介** 203 | 204 |   LuaViewSDK是一个跨平台的框架,旨在构建本地,动态和快速的用户界面。 它基于Lua VM,并选择lua作为脚本语言。 205 |   LuaView 是一种运行在一个 ViewController/Activity 中,可以灵活加载Lua 脚本,并能够按照 Native 的方式 206 | 运行的一种面向业务的开发技术方案。可以快速开发电商应用中既要求体验又要求灵活性的页面功能。例如首页,类目首页, 207 | 垂直频道,大促活动会场等。 208 | 209 | **(2) 背景** 210 |   LuaViewSDK 主要解决客户端开发中的两个常见问题: 211 | 212 | 1.相同的业务逻辑需要在 iOS 和 Android 平台各实现一次,除了开发成本高,也会引入体验的细微差别。 213 | 是否有一种技术方案可以做到一份代码,两个平台运行,行为相同 ? 214 | 2.移动 APP 开发领域,要极致体验发布就不灵活(Native),要灵活发布就没有极致体验(H5)。 215 | 有没有一种技术方案可以兼顾极致的体验和灵活的发布?LuaView 可以完美解决上述两个问题。 216 | 217 | **(3) 为何使用Lua?** 218 | 219 | 市面上有许多类似的方案,比如React Native和Weex,他们使用了JS框架,配合DSL来进行界面布局,使用JS引擎进行脚本动态解析,实现了动态化的Native界面渲染能力。LuaViewSDK使用lua虚拟机进行脚本解析,通过构建lua与native之间的一系列基础bridge功能,从另一个角度实现了动态化的native能力。 220 | 221 | 相比于基于JS虚拟机的解决方案,LuaViewSDK选择的lua有如下优势: 222 | 223 | 1.lua虚拟机极为轻量高效。单个lua虚拟机只消耗大约200到300k的内存空间,同屏渲染几十个LuaView没有任何负担 224 | 2.lua天生就是作为一个极其轻量、可嵌入的设计实现,它更适合做API的封装或是数据传输的中间层。 225 | 在App的开发上,更适合作为胶水语言,来直接操作native对象 226 | 3.lua语法精炼,直观,native开发人员上手基本没有难度 227 | 4.使用native开发人员更为熟悉的Native编程模式,直接创建和操作各种界面对象 228 | 229 | 230 | [github地址:LuaViewSDK](http://git.oschina.net/mirrors/luaviewsdk) 231 | 232 | [LuaViewSDK 文档地址](https://alibaba.github.io/LuaViewSDK/guide.html) 233 | 234 | `另外:` 235 | https://github.com/alibaba/LuaViewPlayground 这个库是对LuaViewSDK的一个补充,用来向开发者展示如何使用LuaViewSDK的基础控件、基本功能,以及如何扩展组件。 236 | 237 | > **4.Thera** 238 |   Thera是由Alibaba.com提供支持的集成开发环境(IDE),旨在改进移动混合解决方案的开发体验,例如weex,luaview,react native。 239 | 240 | [github地址: Thera](https://github.com/alibaba/Thera) 241 | [Thera中文文档](https://github.com/alibaba/Thera/wiki/readme-cn) 242 | 243 | 244 | #### (四)编译、解析、埋点工具有关 245 | 246 | >**1. freeline(我本人目前用这个用得最多,比自带的编译速度快多了)** 247 | 248 |   它是一个Android Studio的插件,可以在Android Studio的插件库查找到,下载安装直接使用。这里列举的是阿里巴巴在github的官网源码。 249 |   Freeline 是 Android 平台上的秒级编译方案,Instant Run 的替代品,也可以从 [Freeline 官方主页](https://www.freelinebuild.com/) 来获取更多的信息。 250 |   Freeline 由 [蚂蚁聚宝](https://www.antfortune.com/) Android 团队开发,它可以充分利用缓存文件,在几秒钟内迅速地对代码的改动进行编译并部署到设备上,有效地减少了日常开发中的大量重新编译与安装的耗时。 251 |   Freeline能够为Android开发者节省很多喝杯咖啡的时间。 252 | 253 | 功能: 254 | 255 | 1.支持标准的多模块 Gradle 工程的增量构建 256 | 2.并发执行增量编译任务 257 | 3.进程级别异常隔离机制 258 | 4.支持 so 动态更新 259 | 5.支持 resource.arsc 缓存 260 | 6.支持 retrolambda 261 | 7.支持 DataBinding 262 | 8.支持各类主流注解库 263 | 9.支持 Windows,Linux,Mac 平台 264 | 265 | [github地址:freeline](https://github.com/alibaba/freeline) 266 | 267 | >**2. fastjson** 268 | 269 |   Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。 270 | 271 | [github地址: fastjson](https://github.com/alibaba/fastjson) 272 | 273 | 274 | >**3.android_viewtracker** 275 | 276 |   ViewTracker是用于自动化的采集用户UI交互过程中的点击和曝光事件,基于view事件代理及过滤的数据采集库。 277 | 278 | 功能: 279 | 280 | 1.支持`Android`&`iOS`平台。 281 | 2.支持采集点击事件、曝光事件。 282 | 3.支持采集页面公共信息。 283 | 4.支持多个场景:列表滑动,列表自动滚动,页面内`Window`切换,`Tab`页切换,进入下一个页面,应用前后台切换。 284 | 5.支持扩展:数据提交、曝光规则自定义(时间阈值和宽高阈值)、采样率定义等。 285 | 286 | [github地址:android_viewtracker](https://github.com/alibaba/android_viewtracker) 287 | 288 | 289 | #### (五)测试、文档工具有关 290 | 291 | > **1. 移动自动化测试平台 Athrun** 292 | 293 |   Athrun以Mobile自动化为基础,以PC2Mobile为切入点,是淘宝Mobile测试日常工作必备的平台。 294 |   **目前Athrun支持:** 295 |   1. Android上的自动化测试,包括自动化测试框架,持续集成体系。覆盖率工具和自动录制回放工具,也在试用完善中。 296 |   2. iOS上的自动化测试,包括注入式自动化框架AppFramework,和基于录制的非注入式自动化框架Athrun_IOS,还有持续集成体系。目前两个框架在淘宝测试内都有用户群,都还在不断使用和演进过程中。AppFramework将会支持socket通信方式。 297 |   AthrunStudio是基于PC2Mobile的移动工作平台,目前正在开发中。Demo代码开源,可以实现PC对手机的远程控制。 298 | 299 | >**2.接口文档管理工具 RAP** 300 | 301 |   RAP通过GUI工具帮助WEB工程师更高效的管理接口文档,同时通过分析接口结构自动生成Mock数据、校验真实接口的正确性,使接口文档成为开发流程中的强依赖。有了结构化的API数据,RAP可以做的更多,而我们可以避免更多重复劳动。 302 | 303 | [github地址:RAP](https://github.com/thx/RAP) 304 | 305 | >**3.Macaca** 306 |   一套完整的自动化测试解决方案 307 | 308 | 特点: 309 | 310 | 1.支持移动端和PC端 311 | 2.支持 Native, Hybrid, H5 等多种应用类型 312 | 3.提供客户端工具和持续集成服务 313 | 314 | [github地址:Macaca](https://github.com/alibaba/macaca) 315 | 316 | >**4.GCanvas** 317 | github地址 https://github.com/alibaba/GCanvas 318 | 码云地址 https://gitee.com/mirrors/GCanvas 319 | 320 | GCanvas 是由淘宝开发的针对移动设备的跨平台渲染引擎。 它使用 C ++ 编写,基于 OpenGL ES,可为 Javascript 运行时提供高性能的 2D / WebGL 渲染。它也具有类似浏览器的画布 API ,因此使用起来非常方便和灵活,尤其适用于 Web 开发人员。 321 | 322 | GCanvas 支持 Android 4.0+(API 14)和 iOS 8.0+ 。支持 Weex 和 ReactNative 等混合框架。 它还可以利用大多数设备上的硬件加速,使得开发者可以使用 Javascript 以非常高的帧率绘制场景。 323 | 324 | 325 | ## 二、腾讯 326 | 327 | >**1. 随身调测平台 GT** 328 | 329 |   GT(随身调)是APP的随身调测平台,它是直接运行在手机上的“集成调测环境”(IDTE, Integrated Debug Environment)。利用GT,仅凭一部手机,无需连接电脑,您即可对APP进行快速的性能测试(CPU、内存、流量、电量、帧率/流畅度等等)、 开发日志的查看、Crash日志查看、网络数据包的抓取、APP内部参数的调试、真机代码耗时统计等。如果您觉得GT提供的功能还不够满足您的需要,您还 可以利用GT提供的基础API自行开发有特殊功能的GT插件,帮助您解决更加复杂的APP调试问题。 330 | 331 | [github地址:GT](https://github.com/TencentOpen/GT) 332 | 333 | >**2. Frozen UI 移动端UI框架** 334 | 335 |   Frozen UI是一个开源的简单易用,轻量快捷的移动端UI框架。基于手Q样式规范,选取最常用的组件,做成手Q公用离线包减少请求,升级方式友好,文档完善,目前全面应用在腾讯手Q增值业务中。 336 | 337 | [github地址:Frozen UI](https://github.com/frozenui/frozenui) 338 | 339 | >**3. AlloyTouch** 340 | 341 |   丝般顺滑的触摸运动方案。这是一个给Web app使用的一个库。这里面包含有一个 **[级联选择器](https://github.com/AlloyTeam/AlloyTouch/tree/master/select) 。** 342 | 343 | [github地址:AlloyTouch](https://github.com/AlloyTeam/AlloyTouch) 344 | 查看文档请点击: https://github.com/AlloyTeam/AlloyTouch/wiki 345 | 346 | >**4. AlloyFinger** 347 | 348 |   轻量级的多点触摸网络手势库,用于web app的一个库。 349 | 350 | [github地址:AlloyFinger](https://github.com/AlloyTeam/AlloyFinger) 351 | 352 | >**5. AlloyCrop** 353 | 354 |   最好且最小的移动裁剪组件,用于web app的一个库。 355 | 356 | [github地址:AlloyFinger](https://github.com/AlloyTeam/AlloyCrop) 357 | 358 | >**6. 组件化框架 Omi 和 Omix** 359 | 360 |   Omi(读音 / [ˈomɪ] /, 汉字类似于 欧米) 是一款用于创建Web用户界面的组件化框架,开放并且现代,故得名:Omi。Omi框架提供了渐进增强式的Web开发解决方案,内置完善的支持无限声明式嵌套的组件系统。 361 | 362 | 概括起来包含下面优点和特性: 363 | 364 | 1.良好的兼容性 - 兼容IE8及IE8以上版本(要兼容IE8请使用omi.art.js),完美兼容各种手机平版移动Web程序 365 | 2.超小的尺寸 - 7 kb (gzip) 366 | 3.面向未来的Web架构体系 - 未来DOM很快,而且越来来快! 其实现在DOM已经足够快了:) 367 | 4.不使用虚拟DOM的问题是跨平台渲染更麻烦,Omi未来将提供`omi-canvas`进行跨平台渲染 368 | 5.ES6+ 和 ES5都可以 - Omi提供了ES6+和ES5的两种开发方案。你可以自有选择你喜爱的方式 369 | 6.局部CSS - HTML+ Scoped CSS + JS组成可复用的组件。不用担心组件的CSS会污染组件外的,Omi会帮你处理好一切 370 | 7.模板或指令系统可替换 - 默认使用soda指令系统,开发者可以重写Omi.template方法来使用任意模板引擎或者指令引擎 371 | 8.完全面向对象 - 函数式和面向对象各有优劣,Omi使用完全的面向对象的方式来构建Web程序。而且支持使用TypeScript来编写Omi程序 372 | 9.更自由的更新 - 每个组件都有update和updateSelf方法,自由选择你认为最佳的更新时机和最佳的更新方式。updateSelf不会更新子组件 373 | 10.完善丰富的插件和灵活的插件体系 374 | omi-router ====》 Omi专属的官方Router插件. 375 | omi-finger ====》 Omi的[AlloyFinger](https://github.com/AlloyTeam/AlloyFinger)插件,支持各种触摸事件和手势 376 | omi-transform ====》 Omi的[transformjs](https://alloyteam.github.io/AlloyTouch/transformjs/)插件,快速方便地设置DOM的CSS3 Transform属性 377 | omi-touch ====》 Omi的[AlloyTouch](https://github.com/AlloyTeam/AlloyTouch)插件,Omi项目的触摸运动解决方案(支持触摸滚动、旋转、翻页、选择等等) 378 | omi-jquery-date-picker ====》 Omi的时间选择插件,支持各种时间或者时间区域选择 379 | 380 | [github地址:Omi](https://github.com/AlloyTeam/omi) 381 | 382 | >**7. 组件化框架Omix** 383 | 384 |   Omix(读音 / [ˈomɪkɜ:s] /, 汉字类似于 欧米可思) 是一款使用 JSX 创建Web用户界面的组件化框架,故得名:Omix。它并不是用来替代 [Omi框架](https://github.com/AlloyTeam/omi),而是另外一种选择。 385 | 386 | 概括起来包含下面优点和特性: 387 | 388 | 1.超迅捷的性能,经过测试, 居然是所有框架第一名, 不信可以看看[dbmon with omix](https://alloyteam.github.io/omix/example/perfs)。虽然排第一,但是发现还有许多优化空间!! 389 | 2.良好的兼容性 - 兼容 IE8,兼容各种手机平版移动 Web 程序 390 | 3.超小的尺寸 - 7 kb (gzip) 391 | 4.内置支持 JSX 和 hyperscript , 喜欢哪种方式随意切换。需要注意 omix 里写 JSX 组件标签要小写 392 | 5.局部CSS - HTML+ Scoped CSS + JS组成可复用的组件。不用担心组件的CSS会污染组件外的 393 | 6.更自由的更新 - 每个组件都有 update 方法,自由选择你认为最佳的更新时机和最佳的更新方式 394 | 7.灵活的插件体系和丰富的插件生态 395 | omi-router ====》 Omi专属的官方Router插件. 396 | omi-finger ====》 Omi的[AlloyFinger](https://github.com/AlloyTeam/AlloyFinger)插件,支持各种触摸事件和手势 397 | omi-transform ====》 Omi的[transformjs](https://alloyteam.github.io/AlloyTouch/transformjs/)插件,快速方便地设置DOM的CSS3 Transform属性 398 | omi-touch ====》 Omi的[AlloyTouch](https://github.com/AlloyTeam/AlloyTouch)插件,Omi项目的触摸运动解决方案(支持触摸滚动、旋转、翻页、选择等等) 399 | 400 | [github地址:Omix](https://github.com/AlloyTeam/omix) 401 | 402 | >**8.JX** 403 | 404 |   JX 是 Javascript eXtension tools 的缩写,即 Javascript 扩展工具套件的意思。一个类似 Google Closure Library 的 Web 前端开发框架。JX 框架同时适用于 Web Page 和 Web App 项目的开发,特别适合构建和组织大规模、工业级的Web App,腾讯 WebQQ -、腾讯 Q+等产品都是采用JX框架开发,兼容目前所有主流浏览器。 405 | 406 | **特性:** 407 | 408 | 1.微内核设计:内核可完全分离出来,用于构建其他的框架 409 | 2.原生对象零污染:你懂的,随着js的App越来约复杂,对原生对象的零污染也体现的越来越重要了 410 | 3.模块封包:采用命名空间、闭包等方式建立了模块封包的体系,帮助更好的组织海量js代码 411 | 4.模块自由拼装:自身模块做了良好的架构分离,尽可能让各个模块之间可以自由的拼装组合 412 | 5.无缝集成各种js框架:与jQuery, YUI, Mootools, Prototype.js 等框架无缝集成;与多种局部框架无缝集成,如:Mini, Sizzle, cssQuery, xpath, JSON 等等 413 | 6.多版本共存:如采用的Jx版本过旧,旧有的Javascript代码不能与新版本Jx兼容,则可以采用多版本共存的方式保持程序的可延续性 414 | 7.分层设计:Javascript核心层,与Javascript解释引擎无关的封装和扩展;浏览器端Javascript层,对浏览器中的Javascript引擎部分的封装和扩展 415 | 416 | [github地址: JX](https://github.com/AlloyTeam/JX) 417 | 418 | >**9. [WeTest-Assistant](https://github.com/Tencent/WeTest-Assistant)** 419 | 420 |   这是基于手机端的辅助测试工具,目前包括性能测试和远程调试两大功能,能够为手游等项目发现CPU、内存、FPS等性能问题,并提供云端真机用于问题在线调试,共计为公司内外部项目服务5.4万次;手游客户端性能测试常用性能维度,CPU,内存,FPS,流量一次性全部收集,图表化展示,数据可按场景化分类,并且支持离线和在线两种模式, 地铁上都可以做测试,Web上看报告。远程调试配合自研的云真机技术,支持多点触控、类手柄遥控,真实还原手游测试场景,极速流畅、极低延迟, 本地只需要一台手机即可操控云端任何一台手机。支持ROOT和非ROOT安卓手机,支持越狱iOS系统。 421 | 422 | >**10.Tinker** 423 | 424 |   Tinker是是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,让应用能够在不需要重新安装的情况下实现更新。当然,你也可以使用Tinker来更新你的插件。 425 | 426 | [github地址:Tinker](https://github.com/Tencent/tinker) 427 | [官方文档](https://github.com/Tencent/tinker/wiki) 428 | 429 | >**11.ncnn** 430 | 431 |   ncnn 是一个为手机端极致优化的高性能神经网络前向计算框架。ncnn 从设计之初深刻考虑手机端的部署和使用。无第三方依赖,跨平台,手机端 cpu 的速度快于目前所有已知的开源框架。基于 ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行,开发出人工智能 APP,将 AI 带到你的指尖。ncnn 目前已在腾讯多款应用中使用,如 QQ,Qzone,微信,天天P图等。 432 | 433 | **功能:** 434 | 435 | 1.支持卷积神经网络,支持多输入和多分支结构,可计算部分分支 436 | 2.无任何第三方库依赖,不依赖 BLAS/NNPACK 等计算框架 437 | 3.纯 C++ 实现,跨平台,支持 android ios 等 438 | 4.ARM NEON 汇编级良心优化,计算速度极快 439 | 5.精细的内存管理和数据结构设计,内存占用极低 440 | 6.支持多核并行计算加速,ARM big.LITTLE cpu 调度优化 441 | 7.整体库体积小于 500K,并可轻松精简到小于 300K 442 | 8.可扩展的模型设计,支持 8bit 量化和半精度浮点存储,可导入 caffe 模型 443 | 9.支持直接内存零拷贝引用加载网络模型 444 | 10.可注册自定义层实现并扩展 445 | 446 | [github地址:ncnn](https://github.com/Tencent/ncnn) 447 | 448 | >**12.RapidView** 449 | 450 |   RapidView是一套用于开发Android客户端界面、逻辑以及功能的开发组件。布局文件(XML)及逻辑文件(Lua)可以运行时执行,主要用以解决Android客户端界面、逻辑快速更新以及快速开发的诉求。RapidView的XML语法规则与Android原生XML类似,而写逻辑的Lua部分除语言语法规则外,可以直接使用我们提供的Java API以及Android原生API,因此熟悉Android客户端开发的开发者上手成本会非常小。 451 | 452 | [github地址:RapidView](https://github.com/Tencent/RapidView) 453 | [官方文档](https://github.com/Tencent/RapidView/blob/master/document.md) 454 | 455 | >**13. QMUI Android(QMUI是腾讯的一个团队,web,ios,android三平台都有对应的工具,这里列举的是Android)** 456 | 457 |   QMUI Android 的设计目的是用于辅助快速搭建一个具备基本设计还原效果的 Android 项目,同时利用自身提供的丰富控件及兼容处理,让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。不管是新项目的创建,或是已有项目的维护,均可使开发效率和项目质量得到大幅度提升。 458 | 459 | QMUI Android 官网:http://qmuiteam.com/android/page/index.html 460 | QMUI Android Github源码查看:https://github.com/QMUI/QMUI_Android 461 | 462 | ## 三、百度 463 | 464 | 百度关于web的开源库很多,关于移动端的库很少。 465 | 466 | > **1. [Android自动化测试框架 Cafe](https://github.com/BaiduQA/Cafe)** 467 |   Cafe 测试框架是一款来自百度QA部门的具有开创性意义的Android平台的自动化测试框架,框架覆盖了Android自动化测试的各种需求。框架致力于实现跨进程测试、快速测试、深度测试,解决了Android自动化测试中的诸多难题,比如业界一直没有解决的跨进程测试问题。 468 | 469 | > **2. [GMU](https://github.com/gmuteam/GMU)** 470 |   GMU(Global Mobile UI)是百度前端通用组开发的移动端组件库,具有代码体积小、简单、易用等特点,组件内部处理了很多移动端的bug,覆盖机型广,能大大减少开发交互型组件的工作量,非常适合移动端网站项目。 该组件基于zepto的mobile UI组件库,提供webapp、pad端简单易用的UI组件! 471 | 472 | >**3. [移动WebApp开发框架 Cloudajs](https://github.com/Clouda-team/Cloudajs)** 473 |   Clouda是基于node.js的Webapp开发框架,在使用Clouda时需要安装node.js和MongoDB。 474 | 【注】原云端一体框架Cloudajs(Sumeru)更名为 **[RapidJS](https://github.com/Clouda-team/rapid-core)**,全面升级后,变得更加灵巧优雅。 475 | 476 | 477 | 478 | 479 | ## 四、网易 480 | 481 | >**1. Android性能测试工具 [Emmagee](https://github.com/NetEase/Emmagee)** 482 | 483 |   Emmagee是监控指定被测应用在使用过程中占用机器的CPU、内存、流量资源的性能测试小工具。 484 |   支持SDK:Android2.2以及以上版本 485 | 486 |   Emmagee功能介绍 487 | 488 | 1、检测当前时间被测应用占用的CPU使用率以及总体CPU使用量 489 | 2、检测当前时间被测应用占用的内存量,以及占用的总体内存百分比,剩余内存量 490 | 3、检测应用从启动开始到当前时间消耗的流量数 491 | 4、测试数据写入到CSV文件中,同时存储在手机中 492 | 5、可以选择开启浮窗功能,浮窗中实时显示被测应用占用性能数据信息 493 | 6、在浮窗中可以快速启动或者关闭手机的wifi网络 494 | 495 | 496 | 497 | >**2. Android测试自动化框架 [Robotium](https://github.com/RobotiumTech/robotium)** 498 | 499 |   Robotium是一个Android测试自动化框架,全面支持本机和混合应用。 Robotium可以轻松地为Android应用程序编写强大而强大的自动黑盒UI测试。 在Robotium的支持下,测试用例开发人员可以编写功能,系统和用户验收测试场景,跨越多个Android Activities。 500 | 501 | >**3. [pomelo-androidclient ](https://github.com/NetEase/pomelo-androidclient)** 502 | 503 | pomelo-androidclient这是一个用于java和android的pomelo socket.io客户端。该项目基于[socket.io-java-client](https://github.com/Gottox/socket.io-java-client)。pomelo-androidclient是Android的易于使用的pomelo客户端,它也与JRE兼容。 504 | 505 | ## 五、新浪(待发掘。。) 506 | 507 | ## 六、华为(待发掘。。) 508 | 509 | ##七、小米(待发掘。。) 510 | 511 | ##八、360(待发掘。。) 512 | --------------------------------------------------------------------------------