# 資訊科技產業專案設計課程作業 4
[資料還沒完全收集好,不好意思]
[toc]
# JD
## Qualcomm - CPU Architecture and Performance Engineer
[網站連結](https://qualcomm.dejobs.org/hsinchu-city-twn/cpu-architecture-and-performance-engineer-hsinchu-taiwan/93FA2C522BC24BBFAD369793F3607877/job/)
### 工作內容
1. Function and performance model development
2. Performance projection and competitive analysis
3. Performance bottleneck analysis
4. Benchmark and workload characterization
5. Performance, Power, and Area trade-offs study
6. CPU and Machine Learning architecture/micro-architecture research
### 所需能力(最低資格)
1. 熟悉in-order/out-of-order CPU架構與演算法
2. 熟悉C/C++
3. 良好英語讀寫、口說能力
## NVIDIA - Firmware Engineer, DGX
[網站連結](https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite/job/Taiwan-Taipei/Software-Security-Engineer_JR1946742)
### 工作內容
1. Be involved in the definition, architectural design, and development of security firmware for NVIDIA DGX products with an opportunity to craft its future.
2. Assist with defining and making sure software development process meeting security standards.
3. Perform security threat modelling for our software.
4. Design and/or make recommendations for security solutions that apply to the software to satisfy DGX server security guidelines and requirements.
### 所需能力(最低資格)
1. 有軟體設計開發經驗
2. 有linux嵌入式開發經驗
3. 有FreeRTOS背景
4. 熟悉Attack vector相關
5. 熟悉C/C++
## 面試題目整理
### 名詞解釋
1. data section
2. heap
3. stack
### 簡答
1. volatile variable 解釋及用法
2. static variable 解釋及用法
3. 解釋interrupt latency
4. 解釋const概念並舉例
5. 解釋memory
6. LINUX/UNIX系統的比較
### 程式題
1. 解釋semaphore和mutex 及其C++的實作
#### Semaphore.h
```clike=
// Semaphore.h
#pragma once
#include "Event.h"
namespace Threads
{
// 訊號量
class Semaphore : WaitHandle
{
public:
// 無上限
static const int Unlimited = -1;
// 建立訊號量
static unique_ptr<Semaphore> CreateSemaphore(int initialCount, int maxCount = Unlimited);
public:
// 等待一個訊號量
virtual void Wait() = 0;
// 限時等待訊號量
virtual bool Wait(const milliseconds& timeout) = 0;
// 釋放訊號量
virtual void Release() = 0;
// 釋放訊號量指定次數
virtual void Release(int releaseCount) = 0;
// 獲取剩餘訊號量數量.
virtual int GetCurrentCount() const = 0;
// 釋放訊號量物件
virtual void Close() = 0;
};
}
```
#### SemaphoreImpl.h
```clike=
#pragma once
#include "Semaphore.h"
#include <mutex>
#include <atomic>
#include <condition_variable>
namespace Threads
{
// 訊號量實現類
class SemaphoreImpl : public Semaphore
{
mutex m_mutex;
condition_variable m_cond;
atomic<bool> m_bDisposed;
volatile int m_currentCount;
int m_maxCount;
public:
SemaphoreImpl(int initialCount, int maxCount);
// 等待一個訊號量
virtual void Wait();
// 限時等待訊號量
virtual bool Wait(const milliseconds& timeout);
// 釋放訊號量
virtual void Release();
// 釋放訊號量指定次數
virtual void Release(int releaseCount);
// 獲取剩餘訊號量數量.
virtual int GetCurrentCount() const;
// 釋放訊號量物件
virtual void Close();
private:
void CheckDisposed()const;
};
}
```
#### Semaphore.cpp
```clike=
#include "Semaphore.h"
#include "SemaphoreImpl.h"
using namespace Threads;
unique_ptr<Semaphore> Semaphore::CreateSemaphore(int initialCount, int maxCount)
{
if (initialCount < 0)
{
throw out_of_range("initialCount < 0");
}
if (maxCount != Unlimited && (maxCount < initialCount || maxCount < 1))
{
throw out_of_range("maxCount < initialCount || maxCount < 1");
}
return unique_ptr<Semaphore>(new SemaphoreImpl(initialCount, maxCount));
}
```
#### SemaphoreImpl.cpp
```clike=
// SemaphoreImpl.cpp
#include "SemaphoreImpl.h"
using namespace Threads;
SemaphoreImpl::SemaphoreImpl(int initialCount, int maxCount)
:m_currentCount(initialCount), m_maxCount(maxCount),
m_bDisposed(false)
{
}
void Threads::SemaphoreImpl::Wait()
{
unique_lock<mutex> lock(m_mutex);
m_cond.wait(lock, [this] {return GetCurrentCount() > 0; });
--m_currentCount;
}
bool Threads::SemaphoreImpl::Wait(const milliseconds & timeout)
{
unique_lock<mutex> lock(m_mutex);
if (m_cond.wait_for(lock, timeout, [this] {return GetCurrentCount() > 0; }))
{
--m_currentCount;
return true;
}
return false;
}
void Threads::SemaphoreImpl::Release()
{
Release(1);
}
void Threads::SemaphoreImpl::Release(int releaseCount)
{
if (releaseCount < 1)
{
throw invalid_argument("releaseCount < 1");
}
lock_guard<mutex> lock(m_mutex);
CheckDisposed();
if (m_maxCount != Semaphore::Unlimited && GetCurrentCount() + releaseCount > m_maxCount)
{
throw invalid_argument("GetCurrentCount() + releaseCount > m_maxCount");
}
m_currentCount += releaseCount;
do {
m_cond.notify_one();
} while (--releaseCount);
}
int Threads::SemaphoreImpl::GetCurrentCount() const
{
CheckDisposed();
return m_currentCount;
}
void SemaphoreImpl::Close()
{
auto expected = false;
if (!m_bDisposed.compare_exchange_weak(expected, true))
{
return;
}
lock_guard<mutex> lock(m_mutex);
m_cond.notify_all();
}
void Threads::SemaphoreImpl::CheckDisposed() const
{
if (m_bDisposed.load() == true)
{
throw logic_error("SemaphoreImpl Disposed.");
}
```
#### main
```clike=
#include <cstdio>
#include <stdlib.h>
#include <iostream>
#include <memory>
#include <thread>
#include "Semaphore.h"
using namespace std;
using namespace Threads;
using namespace chrono;
int main()
{
auto sem = Semaphore::CreateSemaphore(0);
thread t1([&] {
try
{
while (true)
{
// 等待訊號量
sem->Wait();
cout << "[Thread1] Wake up!" << endl;
}
}
catch (const std::logic_error& e) // 訊號量被銷燬
{
cerr << "[Thread1] : " << e.what() << endl;
}
});
thread t2([&] {
try
{
while (true)
{
if (!sem->Wait(duration_cast<milliseconds>(seconds(5))))
{
cout << "[Thread2] Time out!" << endl;
continue;
}
cout << "[Thread2] Wake up!" << endl;
}
}
catch (const std::logic_error& e) // 訊號量被銷燬
{
cerr << "[Thread2] : " << e.what() << endl;
}
});
thread t3([&] {
try
{
while (true)
{
sem->Wait();
cout << "[Thread3] Wake up!" << endl;
}
}
catch (const std::logic_error& e) // 訊號量被銷燬
{
cerr << "[Thread3] : " << e.what() << endl;
}
});
while (true)
{
int input = 0;
cout << "Please input an integer(-1 to exit): " << endl;
cin >> input;
if (input < 0)
{
sem->Close();
break;
}
sem->Release(max(input % 5, 1));
}
t1.join();
t2.join();
t3.join();
return 0;
}
```