秋招突击——7/12——复习{每日温度、完全平方数、无重复最长子串}——新作{字节面试——控制多线程按照顺序输出}

文章目录

    • 引言
    • 复习
      • 每日温度
        • 复习实现
        • 参考学习
      • 完全平方数
        • 复习实现
        • 参考学习
      • 无重复字符的最长子串
        • 复习实现
        • 参考学习
    • 新作
      • 控制多线程输出
        • Java实现线程——不使用锁实现
        • 使用synchronized关键实现——使用锁实现
        • 使用synchronized、wait和notify关键字实现
    • 总结

引言

  • 今天又要面试字节,不过这次没有上次那么紧张了,平常心,然后去面对就行了,行就行,不行也没有办法撒!反正得好好准备提前批还有秋招的正式批!好好准备吧!
  • 今天多复习几题,整体来说,复习还是挺快的!
  • 对了,今天还得整理一下MySQL中关于锁的相关内容,背八股的时候,总是有点疑惑,今天全过一遍!

复习

每日温度

  • 题目链接
  • 第一次学习链接
复习实现
  • 我记得这道题我是做出来了,然后当时方法和参考方法不同,但是思想大致是相同的,应该要维护两个栈。我是从前往后进行遍历,他是从后往前进行遍历。
  • 整体来说还是很好做的,两个判定情况
    • 当前元素比栈顶元素大,栈内元素弹出,直到一个比他本身大的元素,
    • 当前元素比栈顶元素小,直接入栈。
  • 从后往前进行遍历
class Solution {
    public int[] dailyTemperatures(int[] tempe) {
        // define the result array
        int m = tempe.length;
        int[] res = new int[m];

        // define the compare stack
        Deque<Integer> stk = new LinkedList<>();

        // trasverse the tempe
        stk.push(m - 1);
        for(int i = m - 2;i >= 0;i --){
            if(tempe[stk.peek()] > tempe[i]){
                res[i] = stk.peek() - i ;
                stk.push(i);
                

            }else{
                while( !stk.isEmpty() && tempe[stk.peek()] <= tempe[i]){
                    stk.pop();
                }
                if(!stk.isEmpty())   res[i] = stk.peek() - i;
                stk.push(i);
            }
        }

        return res;

    }
}

总结

  • 我这里还调整了蛮久的,不行呀,写出来的代码还那么繁琐!
  • 关于多态有了更加深刻的理解,你要使用队列或者堆栈的功能,就要使用对应的父类接口来承接对应接口实现类的实例对象,才能调用对应的方法。
    • 不要子类直接调用,这样方法太多了,代码可读性也不好!
      在这里插入图片描述
参考学习

参考代码

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temp) {
        int m = temp.size();
        vector<int> f(m);
        stack<int> upst;
        for(int i = temp.size() - 1;i >= 0;i --){
            while(!upst.empty() && temp[i] >= temp[upst.top()]) upst.pop();
            if(upst.size())  f[i] = upst.top() - i;
            upst.push(i);
        }
       
        return f;
    }
};

修改之后的代码

  • 确实更加简洁了,继续再弄吧!
class Solution {
    public int[] dailyTemperatures(int[] tempe) {
        // define the result array
        int m = tempe.length;
        int[] res = new int[m];

        // define the compare stack
        Deque<Integer> stk = new LinkedList<>();

        // trasverse the tempe
        for(int i = m - 1;i >= 0;i --){
            while( !stk.isEmpty() && tempe[stk.peek()] <= tempe[i])    stk.pop();
            if(!stk.isEmpty())   res[i] = stk.peek() - i;
            stk.push(i);
        }

        return res;

    }
}

还是得记录模板,不然做不下去!自己推,根本没有那么多时间!
关于背包集合的问题模板,可以看一下“铅笔大佬”的总结

完全平方数

  • 第一次学习链接
  • 题目链接
复习实现
  • 第二次再看,这个题目就是一个完全背包的问题,背包的物品就是对应的平方数,然后容量就是当前的数字。
class Solution {
    public int numSquares(int n) {
        // define the square number of n
        List<Integer> sqt = new LinkedList<>();
        for(int i = 1;i * i <= n;i++ )  sqt.add(i * i);

        // travser all the situation based on the bag problem
        int[] f = new int[n + 1];
        Arrays.fill(f,n);
        
        int m = sqt.size();
        for(int i = m - 1;i >= 0;i --){
            for(int j = n ;j >= sqt.get(i);j --)
                for(int k = 0;k * sqt.get(i) <= j;k ++)
                    f[j] = Math.min(f[j],f[j - k * sqt.get(i)] + k);
        }
        return f[n - 1];
    }
}

在这里插入图片描述
总结

  • 完全背包的模板没有背下来,没整明白,然后优化模板也没有背下来,不能每次都推导,在浪费时间。
  • 这应该不全是一个完全背包问题,还是不够扎实!

完全背包模板

  • 这多香,往上一套,直接用,可惜你没背出来
  • “找个就放,放满为止;剩余容量,加上价值”
for (int i = 1; i <= n; ++ i)
    for (int j = v[i]; j <= m; ++ j)
        f[j] = max(f[j], f[j - v[i]] + w[i]);
参考学习
  • 真的是愚蠢呀,那道题一看到用什么数学定理,你直接跳过了,真行!不是还有完全背包这种解法吗?你不也是没弄好!
  • 完全背包解决!加上模板,直接修改,秒过,这个模板还是得背!
class Solution {
    public int numSquares(int n) {
        // define the square number of n
        List<Integer> sqt = new LinkedList<>();
        for(int i = 1;i * i <= n;i++ )  sqt.add(i * i);

        // travser all the situation based on the bag problem
        int[] f = new int[n + 1];
        Arrays.fill(f,n);
        f[0] = 0;
        int m = sqt.size();
        for(int i = 0;i < m;i ++){
            for(int j = sqt.get(i) ;j <= n;j ++)
                f[j] = Math.min(f[j],f[j - sqt.get(i)] + 1);
        }
        return f[n ];
    }
}

在这里插入图片描述
算法二

  • 这里是使用了两个定理,一个是一个数一定能够4个完全平方数表示,所以这题返回的结果最多就是4,然后的如果满足一个等式,就可以用三个数表示,否则不行,这里就需要记住一个东西

判定一个数是否是完全平方数

// 这是一个完全平放数的判定
Math.pow(Math.sqrt(x),2) == x
  • 其他的直到就行了

无重复字符的最长子串

  • 第一次学习

第二次学习

  • 题目链接

  • 笑死,这是华为笔试的那道题,如果今天是华为的笔试,你能做出来吗?再来呗,不知道你能不能在一个题上跌三次跟头!

复习实现
  • 典型的滑动窗口,并且是不包含重复字符的,使用hash实现,整整,看看能不能做出来
class Solution {
    public int lengthOfLongestSubstring(String s) {
        // define dict to remove the multiple word
        Map<Character,Integer> dict = new HashMap<>();

        // travrese the whole s
        int m = s.length();
        int res = 0;
        for(int l = 0,r = 0;r < m;r ++){
            // judge  wherther the new char is exists
            while(dict.getOrDefault(s.charAt(r),0) >= 1) {
                dict.put(s.charAt(l),dict.get(s.charAt(l)) - 1);
                l ++;
            }
            dict.put(s.charAt(r),dict.getOrDefault(s.charAt(r),0) + 1 );
            res = Math.max(res,r - l + 1);
        }
        return res;
    }
}

在这里插入图片描述
这里补充了关于String的一些操作

  • 获取字符串的长度 length()
  • 获取某一个特定的字符,chatAt()
  • 获取子串,substring(beignIdx,endIdx);
参考学习
  • 这里完全可以先添加元素,然后在判定,大概的方式是一样的!
int lengthOfLongestSubstring(string s) {
    unordered_map<char,int> heap;
    int res = 0;
    for (int i = 0 ,j = 0; i < s.size(); ++i) {
        heap[s[i]] ++;
        while(heap[s[i]] > 1)
            heap[s[j ++]] --;
        res = max(res,i - j + 1);
    }
    return res;
}

新作

控制多线程输出

  • 线程一,循环输出的1,线程二,循环输出2,线程三,循环输出3,写一个程序,控制这三个线程循环输出1,2,3,1,2,3,…
  • 这个欠缺的知识有点多,一时间不知道怎么弄,这里先补充一下
Java实现线程——不使用锁实现
  • 实现runnable接口的具体类
    • 重写runnable方法,然后在一个thread对象中传入对应的新实例,创建对应线程,然后进行运行
 public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadTest(1));
        Thread t2 = new Thread(new ThreadTest(2));
        Thread t3 = new Thread(new ThreadTest(3));
        t1.start();
        t2.start();
        t3.start();
    }

    static class ThreadTest implements Runnable{

        int num = 0;

        ThreadTest(int val){
            num = val;
        }

        // define recursive function
        private void printNum() throws InterruptedException {
            while(true){
                System.out.print(num);
               Thread.sleep(100);
            }
        }

        @Override
        public void run() {
            try {
                printNum();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

下述是直接实现的效果,并不是完全的123顺序,所以这个方法并不合理!
在这里插入图片描述

版本一,通过全局变量实现控制输出的123

  • 这里虽然有多个线程,但是他们都是Main的内部类,以及内部实例,是共享一个静态变量的current,所以通过current进行设置即可!
public class Main {
    private static int current = 1;
    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadTest(1));
        Thread t2 = new Thread(new ThreadTest(2));
        Thread t3 = new Thread(new ThreadTest(3));
        t1.start();
        t2.start();
        t3.start();
    }
    static class ThreadTest implements Runnable{

        int num = 0;

        ThreadTest(int val){
            num = val;
        }

        // define recursive function
        private void printNum() throws InterruptedException {
            while(true){
                if (current == num){
                    System.out.print(num);
                    current ++;
                }
                if(current == 4)    current = 1;
               Thread.sleep(100);
            }
        }

        @Override
        public void run() {
            try {
                printNum();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

问题

  • 如果不使用对应锁进行控制,三个线程同时在输出前阻塞,然后输出顺序就没有办法控制了!仅仅是在这个简单程序出问题的概率比较低,如果复杂程序出问题的概率就高了!
使用synchronized关键实现——使用锁实现

synchronized关键字介绍

  • 修饰函数,多个线程只能互斥访问这个函数
  • 修饰代码块,多个线程只能访问特定的代码块(需要使用对象锁)

不使用synchronized实现方法
在这里插入图片描述
使用synchronized方法效果

  • 下文使用了synchronized方法之后的效果
public class Main {
    private static int current = 1;
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadTest(1));
        Thread t2 = new Thread(new ThreadTest(2));
        Thread t3 = new Thread(new ThreadTest(3));
        t1.start();
        t2.start();
        t3.start();
    }

    static class ThreadTest implements Runnable{

        int num = 0;

        ThreadTest(int val){
            num = val;
        }

        // define recursive function
        private void printNum() throws InterruptedException {
            synchronized (lock){
                while(true){
                    current ++;
                    System.out.println(current);

                    Thread.sleep(100);
                }
            }

        }

        @Override
        public void run() {
            try {
                printNum();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

在这里插入图片描述

使用synchronized、wait和notify关键字实现

具体实现思路

  • 使用state来表示当前应该的打印那个字母,
  • 每一个线程打印字母之后,就要更新state并且唤醒正在等待的线程
public class Main {
    private static int current = 1;
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable(){
            @Override
            public void run(){
                for(int i = 0;i < 100;i ++){
                    synchronized(lock){
                        // judge whether th current thread should print the num
                        try {
                            // if the current thread should not print num ,wait until the current changed
                            while (current % 3 != 1) {
                                lock.wait();
                            }
                            System.out.println(1);
                            current ++;
                            lock.notifyAll();
                        }catch(InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        });


        Thread t2 = new Thread(new Runnable(){
            @Override
            public void run() {
                // traverse 100 times
                for(int i = 0;i < 100;i ++){
                    synchronized(lock){
                        try{
                            while(current % 3 != 2){
                                lock.wait();
                            }
                            System.out.println(2);
                            current ++;
                            lock.notifyAll();
                        }catch(InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        Thread t3 = new Thread(new Runnable(){
            @Override
            public void run(){
                for(int i = 0;i < 100;i ++){
                    synchronized(lock){
                        try{
                            while(current % 3 != 0) {
                                lock.wait();
                            }
                            System.out.println(3);
                            current ++;
                            lock.notifyAll();
                        }catch(InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }


}

这里有几个东西还是需要记住的

  • 重写的是Overirde,第一个字母是大写
  • notify和wait是会出现interruptedException异常
  • 打印输出异常信息是e.printStackTrace()

总结

  • 不行,太晚了,今天搞得太晚了,放弃,明天在弄吧,面试完了,整个人又开始放松了,然后开始摆烂了!明天得有好多东西需要补充学习,尤其是多线程编程那里,需要好好补充!趁着周六,加油,好好看看!
  • 今天面试字节应该是凉了,感觉没戏了!
  • 不想了,继续往下做吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/798132.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSS相对定位和绝对定位的区别

CSS相对定位和绝对定位的区别 区别1&#xff1a;相对的对象不同 相对定位是相对于自己绝对定位是相对于离自己最近的有定位的祖先 区别2:是否会脱离文档流 相对定位不会脱离文档流&#xff0c;不会影响其他元素的位置绝对定位会脱离文档流&#xff0c;会影响其他元素的布局 代…

MAC通过SSH连接VirtualBox中的虚拟机

1、虚拟机网络连接方式使用桥接方式-桥接网卡 2、重启虚拟机&#xff0c;查看虚拟机ip地址是否跟Mac宿主机在同一网段 3、SSH工具&#xff08;推荐Tabby&#xff09;输入IP、用户名和密码就能连接虚拟机了

JS进阶-异常处理

学习目标&#xff1a; 掌握异常处理 学习内容&#xff1a; throw抛异常try/catch捕获异常debugger throw抛异常&#xff1a; 异常处理是预估代码执行过程中可能发生的错误&#xff0c;然后最大程度的避免错误的发生导致整个程序无法继续运行。 <title>throw抛异常</…

基于AT89C51单片机的多功能自行车测速计程器(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于AT89C51单片机的多功能自行车测速计程器的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 选题背景 原理图 PCB图 仿真图 代码 系统论文 资源下载 选题背景 美丽的夜晚&…

Ubuntu 安装 XRDP,替代系统自带RDP远程桌面

起因&#xff0c;Ubuntu的自带RDP远程桌面很好用&#xff0c;但很傻卵&#xff0c;必须登录。 而设置了自动登录也不能解开KEYRING&#xff0c;必须必须必须用GUI手动登录。 &#xff08;我远程我用头给你坐机子面前开显示器先登录&#xff1f;&#xff1f;&#xff09; 比起VN…

Linux - 基础开发工具(yum、vim、gcc、g++、make/Makefile、git)

目录 Linux软件包管理器 - yum Linux下安装软件的方式 认识yum 查找软件包 安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 vim命令模式各命令汇总 vim底行模式各命令汇总 vim的简单配置 Linux编译器 - gc…

网络技术相关知识概念

网络技术&#xff1a; 进程&#xff08;Process&#xff09; 定义&#xff1a;进程是程序的一次执行过程&#xff0c;它有自己的内存空间和系统资源&#xff08;资源独立&#xff09;。特性&#xff1a; 每个进程都有唯一的PID&#xff08;进程ID&#xff09;。进程间通信&am…

笔记 4 :linux 0.11 中继续分析 0 号进程创建一号进程的 fork () 函数

&#xff08;27&#xff09;本条目开始&#xff0c; 开始分析 copy_process () 函数&#xff0c;其又会调用别的函数&#xff0c;故先分析别的函数。 get_free_page &#xff08;&#xff09; &#xff1b; 先 介绍汇编指令 scasb &#xff1a; 以及 指令 sstosd &#xff1a;…

Vue1-Vue核心

目录 Vue简介 官网 介绍与描述 Vue的特点 与其它 JS 框架的关联 Vue周边库 初识Vue Vue模板语法 数据绑定 el与data的两种写法 MVVM模型 数据代理 回顾Object.defineProperty方法 何为数据代理 Vue中的数据代理 数据代理图示 事件处理 事件的基本使用 事件修…

Appium自动化测试系列: 2. 使用Appium启动APP(真机)

历史文章&#xff1a;Appium自动化测试系列: 1. Mac安装配置Appium_mac安装appium-CSDN博客 一、准备工作 1. 安卓测试机打开调试模式&#xff0c;然后使用可以传输数据的数据线连接上你的电脑。注意&#xff1a;你的数据线一定要支持传输数据&#xff0c;有的数据线只支持充…

MySQL:库操作

1. 创建数据库 create database [if not exists] name [create_specification], [create_specification]... []内为可选的选项 create_specification: character set charset_name -- 指定数据库采用的字符集 -- 数据库未来存储数据 collate collation_name -- 指定数据库字符…

Python3极简教程(一小时学完)下

目录 PEP8 代码风格指南 知识点 介绍 愚蠢的一致性就像没脑子的妖怪 代码排版 缩进 制表符还是空格 每行最大长度 空行 源文件编码 导入包 字符串引号 表达式和语句中的空格 不能忍受的情况 其他建议 注释 块注释 行内注释 文档字符串 版本注记 命名约定 …

github actions方式拉取docker镜像

参考&#xff1a; https://wkdaily.cpolar.cn/archives/gc 注意github actions提供的免费虚拟机空间有限&#xff0c;空间不足会报错&#xff0c;查看大概语句有10来G 我在workflow file里加了df -h 运行查看磁盘情况&#xff1a; 通过pwd命令&#xff0c;可以知道运行目录/ho…

深度加速器 为游戏而生

使用深度加速器的基本步骤如下 首先&#xff0c;访问深度加速器的官方网站或授权下载渠道&#xff0c;下载最新版本的深度加速器客户端。 下载完成后&#xff0c;电脑版直接双击打开免安装&#xff0c;将深度加速器安装到您的计算机或移动设备上。 注册与登录&#xff1a; 打…

OrangePi AI Pro 实测:感受 AI 应用的独特魅力与强大性能

OrangePi AiPro介绍和初始化配置 小寒有话说一、OrangePi AiPro介绍1. 主板详情2. 开发配置3. 镜像烧录4. 设备连接5. WiFi连接6. NVMe SSD的安装和挂载7. 更新下载源并下载必要的软件8. 扩展内存 二、Jupyter Lab AI测评应用案例1. 获取Jupyter Lab 网址链接2. 图像提取文字3.…

python开发prometheus exporter--用于hadoop-yarn监控

首先写python的exporter需要知道Prometheus提供4种类型Metrics 分别是&#xff1a;Counter, Gauge, Summary和Histogram * Counter可以增长&#xff0c;并且在程序重启的时候会被重设为0&#xff0c;常被用于任务个数&#xff0c;总处理时间&#xff0c;错误个数等只增不减的指…

电脑硬盘里的文件能保存多久?电脑硬盘文件突然没了怎么办

在数字化时代&#xff0c;电脑硬盘作为我们存储和访问数据的重要设备&#xff0c;承载着无数珍贵的回忆、工作成果和创意灵感。然而&#xff0c;硬盘里的文件能保存多久&#xff1f;当这些文件突然消失时&#xff0c;我们又该如何应对&#xff1f;本文将深入探讨这两个问题&…

【Python】深入了解`zip()`函数:高效地组合迭代对象

文章目录 1. zip()函数的基本用法2. 处理不同长度的可迭代对象3. 解压缩序列4. 使用zip()处理多个可迭代对象5. 结合for循环使用zip()6. 与字典结合使用7. 处理嵌套结构8. 与*运算符结合使用9. 实际应用示例&#xff1a;合并多个数据源10. 总结 Python中的zip()函数是一个强大且…

71.WEB渗透测试-信息收集- WAF、框架组件识别(11)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;70.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;10&#xff09;-CSDN博客 如果有…

【Python 项目】类鸟群:仿真鸟群

类鸟群&#xff1a;仿真鸟群 仔细观察一群鸟或一群鱼&#xff0c;你会发现&#xff0c;虽然群体由个体生物组成&#xff0c;但该群体作为一个整体似乎有它自己的生命。鸟群中的鸟在移动、飞越和绕过障碍物时&#xff0c;彼此之间相互定位。受到打扰或惊吓时会破坏编队&#xf…