2021春招冲刺-1223 进程线程的通信 | 字符串是否有效 | 数组转换与展平

2021春招冲刺

12.23日

1.操作系统 | 进程之间如何通信 线程之间如何通信

孩子直接傻了。操作系统学了跟白学一样,这个好复杂没有考就没有复习。这里就列出通信方式名字了,详细原理看搬运博客吧 -> 参考博客

进程之间通信

  • 管道
    • 普通管道PIPE
    • 命令管道s_pipe
    • 命名管道FIFO(有名管道/无名管道)
  • 信号量
    它是一个计数器,记录资源能被多少个进程同时访问。用于控制多进程对临界资源的访问(同步)),并且是非负值。主要作为进程间以及同一进程的不同线程间的同步手段。
    • 临界资源:同一时刻,只能被一个进程访问的资源
    • 临界区:访问临界资源的代码区
    • 原子操作:任何情况下不能被打断的操作。
  • 消息队列
    消息队列是消息的链表,是存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区受限等特点,允许不同进程将格式化的数据流以消息队列形式发送给任意进程。
  • 共享内存
    共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。
  • socket通信

线程之间通信 ->参考博客 | 参考博客2

  • 同步
    指多个线程通过synchronized关键字这种方式来实现线程间的通信。
  • while轮询的方式
  • 使用Object类的wait() 和 notify() 方法
  • 基本LockSupport实现线程间的阻塞和唤醒

2.算法 | 给定一个只包括 []{}() 的字符串,判断字符串是否有效。

输入: "()"    输出: true
输入: "[()]"  输出: true
输入: "{()]"  输出: false

解决思路:其实就是简单的入栈出栈操作,入左边的括号,当是右边的括号的时候看栈顶能否匹配。代码丑陋且不简洁但是意思意思吧(泪目)毕竟差点连链表都忘了

class Solution {

public:
bool isValid(string s) {

    stack<char> mystack;
    string::iterator it;
    
    for(it=s.begin(); it != s.end();)
    {
        
        if(*it=='('|| *it=='[' || *it=='{')//为左括号的时候压栈
        {
            mystack.push(*it);
        }
        else
        {
            if(mystack.size()==0)
            return false;
            
            char kuohao = mystack.top();//获取栈顶值
            mystack.pop();//出栈
            if(*it ==')'){
                 if(kuohao != '(')return false;
                }
            else if(*it==']'){
                if(kuohao != '[')return false;
                }
            else if(*it=='}'){
                if(kuohao != '{')return false;
            }
        }
        it ++;
    }
    if(mystack.size()!=0)
    return false;
    else
    return true;

}
};

3.js | 数组转换 | 把一个一维数组(数据只包含Number)[2,3,4]转为234你有哪些方式

  • 定义字符串s='',循环数组,进行s++;
  • string s = array.toString()或者toLocaleString() 方法转换成按照逗号拼接的字符串,再使用s=s.replace(/,/g,'')方法去除逗号拼接
  • string s = array+[] 按照数组链接防止转换成按照逗号拼接的字符串,再同样使用s=s.replace(/,/g,'')方法去除逗号拼接
  • string s = array.join(""),以空字符串拼接数组
  • array.reduce((a,b)=>a+b, "") ,用函数进行逐个项的拼接。看了谭磊的博客的补充

4.js | 数组展平 | 一个多维数组,转换成一维数组

  • 转字符串 let s=arr.join(',').split(',');首先按照join方法将数组按照逗号拼接,在用split方法分割数组。但是数组中存储数字的形式为字符串,需要map进行再次遍历。let arrnum = s.map(item=>{ return Number(item); });

  • array.flat() 或者 [].concat(array)方法可以将二维数组转换为一维数组,但更多维数组将保留数组选项。如果知道数组为几维数组,则可以使用[1, 2, [3, [4, 5]]].flat(2)方法传递降维次数

  • 使用递归方法进行数组的递归,并用Object.prototype.toString.call()判断数据类型,如果是array就进行递归

    function unid1(arr){
        for(let item of arr){
            if(Object.prototype.toString.call(item).slice(8, -1)==='Array'){
                unid1(item);
            }else{
                result.push(item);
            }
        }
        return result;
    }
    
  • 同样递归的原理,但是使用reduce + concat

    (function(origin){
      function flat_deep_with_reduce(arr){
          //首先reduce 进行返回值sum与每个current进行函数过后的来及
          //使用Array.isArray(item)方法判断current项是否为数组。
          //如果是数组就递归,否则直接concat扁平化当前项进行拼接
          return arr.reduce( (sum,current) => Array.isArray(current) ? sum.concat(flat_deep_with_reduce(current) ) :  sum.concat(current) , [] );
      }
      
      let result = flat_deep_with_reduce(origin);
      console.log(result);
      })([1,2,[3,4,[5,6],7],8]);
    
  • 使用堆栈。其本质依旧是对每一项进行判断

    (function(origin){
      let stack = [...origin] ;
      let converted = [];
    
      while(stack.length){
          let item = stack.pop();    //从堆栈底部 弹出元素
          if(Array.isArray(item)){
               // 如果是数组 就扔回堆栈底部
               // 注意扔回底部的不再是 item这个数组了
               // 使用了 ... 之后 , 扔回去的就是一个 比 item少一维的数组 或者元素了
              stack.push(...item)
          }else{
              // 直到上面某个元素不是数组,将它 推给 converted 顶部
              converted.unshift(item)
          }
      }
      console.log(converted);
        })([1,2,[3,4,[5,6],7],8]);
原文地址:https://www.cnblogs.com/banshanliang/p/14190800.html