• ARTS习惯(6)


    Algorithm

    每周至少做一个Leetcode算法题

    第1道


    【题目来源】

    T8:旋转数组的最小数字,何海涛《剑指Offer》

    【题目】

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。

    例子

    例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

    【解答】

    本题若读者给出顺序遍历的方案,复杂度为O(N),显然没有用到旋转数组的特性,不会是最优解

    注意到有序数组这一条件,利用二分查找写出O(logN)的解法才是面试官想要的

    步骤

    【参考代码】

    package com.pengluo.hht_offer.T08_RotateArray;
    
    public class GetMinInRotateArray {
        /**
         *  解法1:遍历数组,逐一比较
         * @param arr
         */
        public int getMinInRotate1(int[] arr) {
            if (arr == null || arr.length ==0) {
                return -1;
            }
            for (int i=0; i < arr.length; i++) {
                if (arr[i] > arr[i+1]){
                    return arr[i+1];
                }
            }
        }
    
        /**
         *  解法2:二分查找
         * @param arr
         * @return arr[mid]最小值
         */
        public int getMinInRotate2(int[] arr) {
    
            if (arr == null || arr.length ==0) {
                return -1;
            }
    
            int left = 0;
            int right = arr.length - 1;
            int mid = left;
            while (arr[left] >= arr[right] ) {
                //
                if ( 1 == right - left) {
                    mid = right;
                    break;
                }
                mid = (left + right)/2;
                // arr[left]=arr[mid]=arr[right]的特殊情形,单独处理,因为二分查找不能判定mid属于哪个递增数组
                if (arr[left] == arr[right] && arr[left] == arr[mid]) {
                    return minInOrder(arr,left,right);
                }
                // 中间位置在左边递增数组
                if (arr[mid] >= arr[left]) {
                    left = mid;
                } else if (arr[mid] <= arr[right]) {// 中间位置在右边递增数组
                    right = mid;
                }
    
            }
            return arr[mid];
        }
        // 顺序查找
        private int minInOrder(int[] arr,int left, int right) {
            int result = arr[left];
            for (int i = left +1; i <= right; i++) {
                if (result > arr[i]) {
                    result = arr[i];
                }
            }
            return result;
        }
    
    }
    
    

    思考

    Review

    阅读并点评至少1篇英文技术文章

    【原文】:Jeff Atwood The Problem With Logging

    【译文】:

    打日志确实有某种迷人的吸引力。为什么不尽可能多的打日志呢?而且打日志对定位问题有好处,那么到处打日志,有什么坏处呢?

    似乎打日志没有什么坏处,但其实可能以你严重的损害,举个例子看看

    在高负载情形下,一个经典的死锁产生。我不保证你在一个轻负载的App上能看到它,但是在我们的网站平均一天一次的发生它。

    我不怪log4net日志框架,我认为是我们写的垃圾代码负全责。后来我们花费了数天定位这些死锁,......。调用了很多资源,花了很大代价,最后我们确定罪魁祸首:日志策略。多么讽刺!

    我从来就不是一个典型的打日志的超级粉丝

    1. 打日志意味着更多的代码

    2. 打日志并不免费

      日志框架虽然高效,但不是无限快。打日志带来性能开销和增加额外的时间

    3. 如果值得保存到日志文件,值得在用户接口出现

    4. 日志用的越多,你能找到的东西越小

      GB的日志数据太多了,需要花费巨大的脑力处理

    5. 日志文件

    看到这里,你可能会得出”打日志就是浪费时间“的结论。其实我不是反对打日志,我是反对过度的打日志。

    我们已经从 Stack Overflow移除所有的日志,除了依靠exception日志。老实说,我根本没有想念过它在这之后。

    当谈到打日志,正确的答案不是”对,总是尽可能的多使用“。抵制给一切打日志的想法。简单和小范围使用,在大多数显而易见的严重的错误时用日志,确实需要时才使用。

    【点评】:

    作者Jeff Atwood是程序员大牛,Stack Overflow的创始人,认为日志很有吸引力,可以帮助定位问题,但问题和优点一样也很明显,过度的使用会产生很多问题:包括产生冗余的代码,性能的消耗。只有在必须要使用日志的重要场合才建议使用日志,反对过度的使用日志。

    Tip

    学习至少一个技术技巧

    重装win10及Java开发环境

    1. 重装win10系统

      • 重装系统之前,做好数据的备份,硬盘和云盘都可以,硬盘更快,因此我采用的硬盘
      • PE U盘起系统,进入桌面(图1)用分区工具将机械盘HD0和固态盘HD1删除分区并格式化
      • 开机后一直按ESC键进入BIOS,将HD1设置为优先启用,HD0优先级低
      • PE U盘起系统,进入桌面点击安装系统(在这之前,先将240G的固态盘HD1分成2个区,125G为系统盘C,其余为普通盘D)
      • 重装完成后,关机,拔掉U盘,开机自动,自动安装驱动
      • 重启,正常进入win10
        图1

      原来是win7+4G+机械硬盘,更换后是win10+8G DDR3+240G SSD,升级后跟新买的电脑样,运行十分流畅,赞极了。

    2. jdk安装

      • oracle官网下载jdk1.8
      • 安装到本地磁盘,包括:jdk和jre
      • 配置环境变量,同样包括jdk和jre
      • 测试安装是否成功
    3. IDEA安装

      • 下载安装包,我的为2020.1版本
      • 按提示安装即可
    4. Maven

      • 下载maven安装压缩包,解压到本地磁盘
      • 配置环境变量,检查版本‘
      • 新建本地仓库文件夹maven_repository
      • 配置confsettings中本地仓库(标签)、远程镜像源(标签),将镜像配置为国内的镜像,会大大加快下载速度
    5. Mysql

      • 重装系统前,最重要的是将项目的数据库表导出为sql,参考Mysql 一次性备份导出/导入恢复所有数据库
      • 特别注意版本,作者最初装的是latest version(8.0.22),安装后测试与原有的项目不兼容。更换为5.7.32 version工作正常
      • 从官网下载安装压缩包,解压到本地磁盘D:mysql
      • 根目录D:mysqlmysql-5.7.32-winx64下创建data文件夹和my.ini文件,配置my.ini文件
      • 管理员身份运行cmd,执行几条指令进行安装和系统注册表注册,自行搜索安装教程。可参考mysql 8.0.22 安装配置图文教程
      • 安装过程中,可能缺少一些文件和组件,根据报错信息关键字搜索解决即可
      • 设置密码,参考mysql重置密码
      • 导入sql恢复数据库表:mysql>source f:sqlback.sql;
      • 配置完成,正常使用数据库
    6. 其它软件安装

      以下软件安装都比较简单,按提示操作很简单

      • 文件管理软件:Total commander
      • markdown编辑器:Typora
      • 版本控制软件:Git
      • IDE:vs Code
      • 包管理:node.js V10.0.0
      • web测试工具:postman

    孔子说,工欲善其事,必先利其器。此刻,这句名言最能概括我此时的感受。原本我这段时间很忙,担心重装系统及配置环境会耽误太长的时间影响我目前的开发,犹豫了很久。现在看来电脑运行速度提升带来的开发效率提升了20倍以上,为自己的果断决策鼓掌。

    Share

    分享一篇有观点和思考的技术文章

    从0开始学习 GitHub 系列之「团队合作利器 Branch」

    米罗说

    • 掌握时间管理是每个人的必修课

    • 总有人比你NB,还比你更拼命-stormzhang

  • 相关阅读:
    Kubernetes CNI 发展趋势- iptables_ipvs_bpf_ovs
    《设计模式:可复用面向对象软件的基础》之单例模式
    《设计模式:可复用面向对象软件的基础》之策略模式
    Rancher On K3s 高可用架构部署
    学习计算机的体会与认识
    结对编程1-模块化
    个人作业——APP案例分析
    四则运算——二叉树
    IDEA使用Visual Studio的快捷键配置
    【Java学习笔记】写第一个HelloWorld程序,命令行程序
  • 原文地址:https://www.cnblogs.com/PengLuo22/p/14209037.html
Copyright © 2020-2023  润新知