1. 程式人生 > 實用技巧 >2021春招衝刺-1223

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(""),以空字串拼接陣列

3.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]);