diff --git a/Algorithms/basic_knowledge.md b/Algorithms/basic_knowledge.md index cc1f659..bece644 100644 --- a/Algorithms/basic_knowledge.md +++ b/Algorithms/basic_knowledge.md @@ -10,17 +10,17 @@ -![image](/Users/zhaofengyi/Documents/gitbook/Algorithms/pic/discrete_sum.png) +![image](./pic/discrete_sum.png) -![image](/Users/zhaofengyi/Documents/gitbook/Algorithms/pic/common_cost.png) +![image](./pic/common_cost.png) -![image](/Users/zhaofengyi/Documents/gitbook/Algorithms/pic/capability.png) +![image](./pic/capability.png) Theta, O, Omega, Tilde记号: -![image](/Users/zhaofengyi/Documents/gitbook/Algorithms/pic/notation1.png) +![image](./pic/notation1.png) | 记号 | 含义 | | ---------- | ---------------------- | @@ -30,7 +30,7 @@ Theta, O, Omega, Tilde记号: 误区:把O(N)当做近似模型,应该用 ~ N -![image](/Users/zhaofengyi/Documents/gitbook/Algorithms/pic/notation2.png) +![image](./pic/notation2.png) diff --git a/Android/WorkExperience/android.adatper.md b/Android/WorkExperience/android.adatper.md index 725b8d4..67b0518 100644 --- a/Android/WorkExperience/android.adatper.md +++ b/Android/WorkExperience/android.adatper.md @@ -4,22 +4,20 @@ ## 屏幕适配 -1. 用AndroidStudio插件ScreenMatch根据屏幕尺寸生成不同的dimen +#### 定义多种分辨率的dimens.xml(不推荐) + +用AndroidStudio插件ScreenMatch根据屏幕尺寸生成不同的dimen https://www.jianshu.com/p/1302ad5a4b04 https://github.com/wildma/ScreenAdaptation/blob/master/app/src/main/res/values/dimens.xml -不能应对density变化? - -2. 用限制性布局ConstraintLayout - 少用dp值,多用百分比 - 可以应对density变化 +#### 用限制性布局ConstraintLayout +> implementation 'androidx.constraintlayout:constraintlayout:1.1.3' -> implementation 'com.android.support.constraint:constraint-layout:1.1.3' ```xml @@ -67,12 +65,83 @@ https://github.com/wildma/ScreenAdaptation/blob/master/app/src/main/res/values/d ``` -* 图片用.9或者svg; 多用相对布局,尽量不用绝对布局; +#### 用自适应TextView +https://blog.csdn.net/Virgil_K2017/article/details/88725298 + +> implementation 'androidx.appcompat:appcompat:1.1.0' + + +8.0以上: + +```xml + +``` + +8.0以下: + +``` +implementation 'com.android.support:appcompat-v7:28.0.0' +``` + +```xml + +``` + +androidx的话用`androidx.appcompat.widget.AppCompatTextView` + + + +#### 其他 + +* 图片用.9或者svg +* 多用相对布局,尽量不用绝对布局 +* 少用dp值,多用百分比 + + + +## 安卓版本适配 + +通过gradle flavor选择不同的source set -3. 通过gradle flavor选择不同的sourceset -4. 用自适应textview -https://blog.csdn.net/Virgil_K2017/article/details/88725298 diff --git a/Android/WorkExperience/force.landscape.md b/Android/WorkExperience/force.landscape.md index 62912b0..29986bc 100644 --- a/Android/WorkExperience/force.landscape.md +++ b/Android/WorkExperience/force.landscape.md @@ -172,9 +172,22 @@ index 750bad6..6b34af6 100644 ### recovery UI +用命令`convert progress_fill.png -rotate 90 progress_fill.png && convert progress_empty.png -rotate 90 progress_empty.png` 把以下图片旋转90度: + +res-hdpi/images/progress_empty.png + res-hdpi/images/progress_fill.png + res-mdpi/images/progress_empty.png + res-mdpi/images/progress_fill.png + res-xhdpi/images/progress_empty.png + res-xhdpi/images/progress_fill.png + res-xxhdpi/images/progress_empty.png + res-xxhdpi/images/progress_fill.png + res-xxxhdpi/images/progress_empty.png + res-xxxhdpi/images/progress_fill.png + ```cpp diff --git a/screen_ui.cpp b/screen_ui.cpp -index b8f6ea2..69db797 100644 +index b8f6ea2..153d1b1 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -170,8 +170,8 @@ void ScreenRecoveryUI::draw_background_locked() { @@ -199,7 +212,54 @@ index b8f6ea2..69db797 100644 gr_blit(frame, 0, 0, frame_width, frame_height, frame_x, frame_y); } -@@ -460,6 +460,7 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { +@@ -193,8 +193,8 @@ void ScreenRecoveryUI::draw_foreground_locked() { + int width = gr_get_width(progressBarEmpty); + int height = gr_get_height(progressBarEmpty); + +- int progress_x = (gr_fb_width() - width) / 2; +- int progress_y = GetProgressBaseline(); ++ int progress_x = (gr_fb_width() - width) / 5; //(gr_fb_width() - width) / 2; ++ int progress_y = (gr_fb_height() - height) / 2; //GetProgressBaseline(); + + // Erase behind the progress bar (in case this was a progress-only update) + gr_color(0, 0, 0, 255); +@@ -202,24 +202,27 @@ void ScreenRecoveryUI::draw_foreground_locked() { + + if (progressBarType == DETERMINATE) { + float p = progressScopeStart + progress * progressScopeSize; +- int pos = static_cast(p * width); ++ int pos = static_cast(p * height); + + if (rtl_locale_) { + // Fill the progress bar from right to left. + if (pos > 0) { +- gr_blit(progressBarFill, width - pos, 0, pos, height, progress_x + width - pos, +- progress_y); ++ //gr_blit(progressBarFill, width - pos, 0, pos, height, progress_x + width - pos, progress_y); ++ gr_blit(progressBarFill, 0, height - pos, width, pos, progress_x, progress_y + width - pos); + } +- if (pos < width - 1) { +- gr_blit(progressBarEmpty, 0, 0, width - pos, height, progress_x, progress_y); ++ if (pos < height - 1) { ++ //gr_blit(progressBarEmpty, 0, 0, width - pos, height, progress_x, progress_y); ++ gr_blit(progressBarEmpty, 0, 0, width, height - pos, progress_x, progress_y); + } + } else { + // Fill the progress bar from left to right. + if (pos > 0) { +- gr_blit(progressBarFill, 0, 0, pos, height, progress_x, progress_y); ++ //gr_blit(progressBarFill, 0, 0, pos, height, progress_x, progress_y); ++ gr_blit(progressBarFill, 0, 0, width, pos, progress_x, progress_y); + } +- if (pos < width - 1) { +- gr_blit(progressBarEmpty, pos, 0, width - pos, height, progress_x + pos, progress_y); ++ if (pos < height - 1) { ++ //gr_blit(progressBarEmpty, pos, 0, width - pos, height, progress_x + pos, progress_y); ++ gr_blit(progressBarEmpty, 0, pos, width, height - pos, progress_x, progress_y + pos); + } + } + } +@@ -460,6 +463,7 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, GRSurface** surface) { int result = res_create_localized_alpha_surface(filename, locale_.c_str(), surface); @@ -207,7 +267,18 @@ index b8f6ea2..69db797 100644 if (result < 0) { LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")"; } -@@ -841,3 +842,29 @@ void ScreenRecoveryUI::KeyLongPress(int) { +@@ -611,8 +615,8 @@ void ScreenRecoveryUI::SetProgress(float fraction) { + if (fraction > 1.0) fraction = 1.0; + if (progressBarType == DETERMINATE && fraction > progress) { + // Skip updates that aren't visibly different. +- int width = gr_get_width(progressBarEmpty); +- float scale = width * progressScopeSize; ++ int height = gr_get_height(progressBarEmpty); ++ float scale = height * progressScopeSize; + if ((int)(progress * scale) != (int)(fraction * scale)) { + progress = fraction; + update_progress_locked(); +@@ -841,3 +845,29 @@ void ScreenRecoveryUI::KeyLongPress(int) { // will change color to indicate a successful long press. Redraw(); } @@ -236,7 +307,7 @@ index b8f6ea2..69db797 100644 + delete []src; + return; +} -+ ++ ``` ```cpp diff --git a/Android/WorkExperience/gridlayout.height.md b/Android/WorkExperience/gridlayout.height.md new file mode 100644 index 0000000..3ee9197 --- /dev/null +++ b/Android/WorkExperience/gridlayout.height.md @@ -0,0 +1,122 @@ +# GridLayout + +参考: https://www.jianshu.com/p/441d60be7d8a + +GridLayout的每一项宽高只能是: + +wrap_content; + +一个写死的xxdp值; + +根据设置的column平分; + +但是项目需要适配好一点的话,最好可以动态设置宽高。 + +```java +setLayoutManager(new GridLayoutManager(this, columeNum)); +``` + +这样宽可以自动均分了; + +高度是测量第1行中所有子View的高,取最大值作为该行的高,如果该行没有子View,行高设为0。 + +> GridLayout的子View不需要设置layout_width和layout_height属性,因为GridLayout会把所有的子View的这两个属性设置为WRAP_CONTENT,所以你设置了也没有用。 + +1. 高度跟宽一样 + +在子view的onMeasure里面把宽高设成一样 + +```xml + + ... + +``` + + + +```java +package com.moos.launcher; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.constraintlayout.widget.ConstraintLayout; + +public class CustomConstraintlayout extends ConstraintLayout { + public CustomConstraintlayout(Context context) { + super(context); + } + + public CustomConstraintlayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CustomConstraintlayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + + /** + * set height the same size with height; + * gridlayout计算子view最大高度,设置为这一行的高度; + * 但是这里希望直接设置为跟宽度一样,而不用依赖子view的高度; + * 这样子view可以用constraintlayout,根据父view的高度来布局 + * 所有的布局都不需要写dp值,只写比例值即可 + * @param widthMeasureSpec + * @param heightMeasureSpec + */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); + } +} +``` + + + +2. 高度根据父view的高度均分 + +Adatper中设置子view的子view的高度 + +>为什么不设置子view, 因为上面说了,子view不管设置成什么,结果都是wrap_content + +```xml + + + ... + +``` + + + +```java +@NonNull + @Override + public XXXViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.XXX_item, null); + View maxHeightView = view.findViewById(R.id.max_height_view); + ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) maxHeightView.getLayoutParams(); + layoutParams.height = mRecyclerView.getHeight() / 3; + // 这里设置成父view的1/3 + maxHeightView.setLayoutParams(layoutParams); + return new XXXViewHolder(view); + } +``` + diff --git a/Android/WorkExperience/hidden.api.md b/Android/WorkExperience/hidden.api.md new file mode 100644 index 0000000..312035c --- /dev/null +++ b/Android/WorkExperience/hidden.api.md @@ -0,0 +1,71 @@ +[toc] + +# 获得安卓隐藏API + +## 静默获得录屏权限 + +```java + @RequiresApi(21) + private void setMediaProjectionIntentWithoutPermission(Context context) { + if (mMediaProjectionIntent == null) { + String mPackageName = context.getPackageName();; + int mUid = -1; + PackageManager packageManager = context.getPackageManager(); + ApplicationInfo aInfo; + try { + aInfo = packageManager.getApplicationInfo(mPackageName, 0); + mUid = aInfo.uid; + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "unable to look up package name", e); + } + Log.i(TAG, "requestPermissions mPackageName " + mPackageName + ", mUid " + mUid); + try { + Class serviceManager = Class.forName("android.os.ServiceManager"); + IBinder serviceBinder = (IBinder)serviceManager.getMethod("getService", String.class) + .invoke(serviceManager, "media_projection"); + Class stub = Class.forName("android.media.projection.IMediaProjectionManager$Stub"); + Object projectionManagerService = stub.getMethod("asInterface", IBinder.class).invoke(stub, serviceBinder); + Method hasProjectionPermission = projectionManagerService.getClass() + .getMethod("hasProjectionPermission", int.class, String.class); + boolean result = (boolean)hasProjectionPermission.invoke(projectionManagerService, mUid, mPackageName); + Log.i(TAG, "hasProjectionPermission " + result); + + Method createProjection = projectionManagerService.getClass() + .getMethod("createProjection", int.class, String.class, int.class, boolean.class); + Class projectionClass = Class.forName("android.media.projection.IMediaProjection"); + Method asBinderMethod = projectionClass.getMethod("asBinder"); + + Object projectionObj = createProjection.invoke(projectionManagerService, mUid, mPackageName, 0, true); + IBinder projectionBinder = (IBinder)asBinderMethod.invoke(projectionObj); + Intent intent = new Intent(); + Method putBinderExtra = intent.getClass().getMethod("putExtra", String.class, IBinder.class); + putBinderExtra.invoke(intent, "android.media.projection.extra.EXTRA_MEDIA_PROJECTION", projectionBinder); + Log.i(TAG, "successfully get media projection intent"); + mMediaProjectionIntent = intent; + } catch (ClassNotFoundException | ClassCastException | NoSuchMethodException | SecurityException + | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + Log.w(TAG, e.toString()); + e.printStackTrace(); + } + } + } +``` + + + +## 判断是否首次启动或者factory reset后首次启动 + +```java +boolean isFirstBoot = false; + IBinder pmsIBinder = ServiceManager.getService("package"); + try { + Class stub = Class.forName("android.content.pm.IPackageManager$Stub"); + Object pms = stub.getMethod("asInterface", IBinder.class).invoke(stub, pmsIBinder); + isFirstBoot = (boolean)pms.getClass().getMethod("isFirstBoot").invoke(pms); + Log.w(TAG, "setVolumeMaxWhenFirstBoot isFirstBoot " + isFirstBoot); + } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + Log.w(TAG, "setVolumeMaxWhenFirstBoot error " + e.toString()); + } +``` + diff --git a/Android/WorkExperience/recovery.md b/Android/WorkExperience/recovery.md new file mode 100644 index 0000000..8b737ac --- /dev/null +++ b/Android/WorkExperience/recovery.md @@ -0,0 +1,25 @@ +更新bootable/recovery: + +make installclean && make recovery && make -j16 && make otapackage -j16 + + + + + +* 烧板子: + +选择Format All + Download + +* 第二次make otapackage之前 rm -rf out/target/product/tb8735ap1_lr_ztk/obj/PACKAGING/target_files_intermediates/* + +* 差分包制作: + +./build/tools/releasetools/ota_from_target_files -s ./vendor/mediatek/proprietary/scripts/releasetools/mt_ota_from_target_files.py -i ~/ota/old/old.zip ~/ota/new/new.zip update.zip + +* 启动本地升级的apk: + +adb push update.zip /sdcard/ + +am start com.zelustek.usbupgrade/.MainActivity + +点击开始升级按钮 \ No newline at end of file diff --git a/Basic_Knowledge/design.md b/Basic_Knowledge/design.md new file mode 100644 index 0000000..f9c88bc --- /dev/null +++ b/Basic_Knowledge/design.md @@ -0,0 +1,4 @@ +类图: + +image + diff --git "a/Basic_Knowledge/pic/\347\261\273\345\233\276.png" "b/Basic_Knowledge/pic/\347\261\273\345\233\276.png" new file mode 100644 index 0000000..46329c8 Binary files /dev/null and "b/Basic_Knowledge/pic/\347\261\273\345\233\276.png" differ diff --git a/CodeManagement/code.style.check.md b/CodeManagement/code.style.check.md new file mode 100644 index 0000000..69073b8 --- /dev/null +++ b/CodeManagement/code.style.check.md @@ -0,0 +1,10 @@ +![image](./pic/as.checkstyle.plugin.png) + +安装结束后重启 + +![image](./pic/as.checkstyle.plugin2.png) + +https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml + + + diff --git a/CodeManagement/google_checks.xml b/CodeManagement/google_checks.xml new file mode 100644 index 0000000..b787bb3 --- /dev/null +++ b/CodeManagement/google_checks.xml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CodeManagement/pic/as.checkstyle.plugin.png b/CodeManagement/pic/as.checkstyle.plugin.png new file mode 100644 index 0000000..d9649b3 Binary files /dev/null and b/CodeManagement/pic/as.checkstyle.plugin.png differ diff --git a/CodeManagement/pic/as.checkstyle.plugin2.png b/CodeManagement/pic/as.checkstyle.plugin2.png new file mode 100644 index 0000000..0aba7e3 Binary files /dev/null and b/CodeManagement/pic/as.checkstyle.plugin2.png differ diff --git a/Others/interview (copy) (copy).md b/Others/interview (copy) (copy).md new file mode 100644 index 0000000..9692b7f --- /dev/null +++ b/Others/interview (copy) (copy).md @@ -0,0 +1,116 @@ +# 面试出题 + +主要成就: + +Arouter aprovider + +mmqv + +sharepreference单独找出来启动必要的,其他的以后再加载; + +kotlin + +湖北文理学院 + + + +找工作:成长变慢,T3->4, 想升t5 + +加班996, + + + +薪资:>= 24K*14~18个 + +24w税前 + + + + + + + + + +## git工作流程 + +解决冲突; + + + + + +## 堆和栈的区别(程序的分配机制) + +* 栈 + * 编译器自动维护的,不需要程序员显式维护 + * 栈size比较小,创建线程的时候确定栈大小,栈里面存放局部变量和函数调用关系; + * 栈由相应的硬件支持,硬件指令和寄存器; + * 栈是高地址向低地址扩展, 是一块连续的内存区域 +* 堆 + * 一片可以动态分配释放的内存区域,内存维护方式,频繁分配释放可能会引起内存碎片 + * 堆是地地址向高地址分配, 不连续的内存区域 + * 栈上的数据在函数结束后自动释放, 堆上的数据如果不释放, 一直能访问, 可能会造成内存泄漏 + * 栈是先进后出, 不会有内存碎片问题, 堆如果频繁的new/delete 会造成内存空间不连续, 造成大量碎片 + +https://m.php.cn/faq/418027.html + +回答 + + + +## 二分查找 + +```java +public int binarySearch(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return -1; + } + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = start + (end - start) / 2; + if (nums[mid] == target) { + end = mid; + } else if (nums[mid] < target) { + start = mid; + } else if (nums[mid] > target) { + end = mid; + } + } + if (nums[start] == target) { + return start; + } + if (nums[end] == target) { + return end; + } + return -1; +} +``` + +## 插入排序 + +```java +import java.util.Arrays; +public class InsertSort { + public int[] sort(int[] srcArr) { + int[] arr = Arrays.copyOf(srcArr, srcArr.length); + int tmp; + for (int i = 1; i < arr.length; i++) { + tmp = arr[i]; + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + arr[j] = tmp; + } + return arr; + } +} +``` + + + + + diff --git a/Others/interview (copy).md b/Others/interview (copy).md new file mode 100644 index 0000000..12a2430 --- /dev/null +++ b/Others/interview (copy).md @@ -0,0 +1,108 @@ +# 面试出题 + +* 主观感受: + +比较油腻 + +脚手架,可测试,npm管理机制, + +binder + +webview context优化 + + + +薪资: + + 50w年薪 + + + + + +* 主要成就: + + + + + +## git工作流程 + + + + + +## 堆和栈的区别(程序的分配机制) + +* 栈 + * 编译器自动维护的,不需要程序员显式维护 + * 栈size比较小,创建线程的时候确定栈大小,栈里面存放局部变量和函数调用关系; + * 栈由相应的硬件支持,硬件指令和寄存器; + * 栈是高地址向低地址扩展, 是一块连续的内存区域 +* 堆 + * 一片可以动态分配释放的内存区域,内存维护方式,频繁分配释放可能会引起内存碎片 + * 堆是地地址向高地址分配, 不连续的内存区域 + * 栈上的数据在函数结束后自动释放, 堆上的数据如果不释放, 一直能访问, 可能会造成内存泄漏 + * 栈是先进后出, 不会有内存碎片问题, 堆如果频繁的new/delete 会造成内存空间不连续, 造成大量碎片 + +https://m.php.cn/faq/418027.html + +回答 + + + +## 二分查找 + +```java +public int binarySearch(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return -1; + } + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = start + (end - start) / 2; + if (nums[mid] == target) { + end = mid; + } else if (nums[mid] < target) { + start = mid; + } else if (nums[mid] > target) { + end = mid; + } + } + if (nums[start] == target) { + return start; + } + if (nums[end] == target) { + return end; + } + return -1; +} +``` + +## 插入排序 + +```java +import java.util.Arrays; +public class InsertSort { + public int[] sort(int[] srcArr) { + int[] arr = Arrays.copyOf(srcArr, srcArr.length); + int tmp; + for (int i = 1; i < arr.length; i++) { + tmp = arr[i]; + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + arr[j] = tmp; + } + return arr; + } +} +``` + + + + + diff --git a/Others/interview.md b/Others/interview.md new file mode 100644 index 0000000..52b9ac1 --- /dev/null +++ b/Others/interview.md @@ -0,0 +1,118 @@ +# 面试出题 + +主要成就: + +视图模块化; + +Arouter; + +外观模式; + +eventbus观察者模式, + +binder了解, socket, + +ams; + +tinker,封装dex,类的映射, classloader数组; + +jvm, gc新生代 + + + +java 8 c 4,5 + + + +薪资:20K左右 + +15*15K + +3周 + +## git工作流程 + +解决冲突; + +git pull + +git add; git commit; + + + + + +## 堆和栈的区别(程序的分配机制) + +* 栈 + * 编译器自动维护的,不需要程序员显式维护 + * 栈size比较小,创建线程的时候确定栈大小,栈里面存放局部变量和函数调用关系; + * 栈由相应的硬件支持,硬件指令和寄存器; + * 栈是高地址向低地址扩展, 是一块连续的内存区域 +* 堆 + * 一片可以动态分配释放的内存区域,内存维护方式,频繁分配释放可能会引起内存碎片 + * 堆是地地址向高地址分配, 不连续的内存区域 + * 栈上的数据在函数结束后自动释放, 堆上的数据如果不释放, 一直能访问, 可能会造成内存泄漏 + * 栈是先进后出, 不会有内存碎片问题, 堆如果频繁的new/delete 会造成内存空间不连续, 造成大量碎片 + +https://m.php.cn/faq/418027.html + +回答ok + + + +## 二分查找 + +```java +public int binarySearch(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return -1; + } + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = start + (end - start) / 2; + if (nums[mid] == target) { + end = mid; + } else if (nums[mid] < target) { + start = mid; + } else if (nums[mid] > target) { + end = mid; + } + } + if (nums[start] == target) { + return start; + } + if (nums[end] == target) { + return end; + } + return -1; +} +``` + +## 插入排序 + +```java +import java.util.Arrays; +public class InsertSort { + public int[] sort(int[] srcArr) { + int[] arr = Arrays.copyOf(srcArr, srcArr.length); + int tmp; + for (int i = 1; i < arr.length; i++) { + tmp = arr[i]; + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + arr[j] = tmp; + } + return arr; + } +} +``` + + + + +