同步異步,阻塞非阻塞 ,TCP/IP協議 ,快速排序一次後 等C++筆試面試(3)

同步、異步::消息的通知機制

  • 解釋:涉及到IO通知機制;所謂同步,就是發起調用後,被調用者處理消息,必須等處理完才直接返回結果,沒處理完之前是不返回的,調用者主動等待結果;所謂異步,就是發起調用後,被調用者直接返回,但是並沒有返回結果,等處理完消息後,通過狀態、通知或者回調函數來通知調用者,調用者被動接收結果。

阻塞、非阻塞程序等待調用結果時的狀態

  • 涉及到CPU線程調度;所謂阻塞,就是調用結果返回之前,該執行線程會被掛起,不釋放CPU執行權,線程不能做其它事情,只能等待,只有等到調用結果返回了,才能接着往下執行;所謂非阻塞,就是在沒有獲取調用結果時,不是一直等待,線程可以往下執行,如果是同步的,通過輪詢的方式檢查有沒有調用結果返回,如果是異步的,會通知回調。

TCP/IP協議實際上就是在物理網上的一組完整的網絡協議。其中TCP是提供傳輸層服務,而IP則是提供網絡層服務。TCP/IP包括以下協議:

IP: 網間協議(Internet Protocol) 負責主機間數據的路由和網絡上數據的存儲。同時爲ICMP,TCP,   UDP提供分組發送服務。用戶進程通常不需要涉及這一層。
ARP: 地址解析協議(Address Resolution Protocol)
   此協議將網絡地址映射到硬件地址。
RARP: 反向地址解析協議(Reverse Address Resolution Protocol)
   此協議將硬件地址映射到網絡地址
ICMP: 網間報文控制協議(Internet Control Message Protocol)
   此協議處理信關和主機的差錯和傳送控制。
TCP: 傳送控制協議(Transmission Control Protocol)
   這是一種提供給用戶進程的可靠的全雙工字節流面向連接的協議。它要爲用戶進程提供虛電路服務,併爲數據可靠傳輸建立檢查。(注:大多數網絡用戶程序使用TCP)
UDP: 用戶數據報協議(User Datagram Protocol)
   這是提供給用戶進程的無連接協議,用於傳送數據而不執行正確性檢查。
FTP: 文件傳輸協議(File Transfer Protocol)
   允許用戶以文件操作的方式(文件的增、刪、改、查、傳送等)與另一主機相互通信。
SMTP: 簡單郵件傳送協議(Simple Mail Transfer Protocol)
   SMTP協議爲系統之間傳送電子郵件。
TELNET:終端協議(Telnet Terminal Procotol)
   允許用戶以虛終端方式訪問遠程主機
HTTP: 超文本傳輸協議(Hypertext Transfer Procotol)
TFTP: 簡單文件傳輸協議(Trivial File Transfer Protocol)

TCP/IP協議的核心部分是傳輸層協議(TCP、UDP),網絡層協議(IP)和物理接口層,這三層通常是在操作系統內核中實現。因此用戶一般不涉及。編程時,編程界面有兩種形式:一、是由內核心直接提供的系統調用;二、使用以庫函數方式提供的各種函數。前者爲核內實現,後者爲核外實現。用戶服務要通過核外的應用程序才能實現,所以要使用套接字(socket)來實現。

、基本套接字

  爲了更好說明套接字編程原理,給出幾個基本的套接字,在以後的篇幅中會給出更詳細的使用說明。

  1、創建套接字——socket()

  功能:使用前創建一個新的套接字

  格式:SOCKET PASCAL FAR socket(int af,int type,int procotol);

  參數:af: 通信發生的區域

  type: 要建立的套接字類型

  procotol: 使用的特定協議

  2、指定本地地址——bind()

  功能:將套接字地址與所創建的套接字號聯繫起來。

  格式:int PASCAL FAR bind(SOCKET s,const struct sockaddr FAR * name,int namelen);

  參數:s: 是由socket()調用返回的並且未作連接的套接字描述符(套接字號)。

  其它:沒有錯誤,bind()返回0,否則SOCKET_ERROR

  地址結構說明:

struct sockaddr_in
{
short sin_family;//AF_INET
u_short sin_port;//16位端口號,網絡字節順序
struct in_addr sin_addr;//32位IP地址,網絡字節順序
char sin_zero[8];//保留
}

  3、建立套接字連接——connect()和accept()

  功能:共同完成連接工作

  格式:int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR * name,int namelen);

  SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR * name,int FAR * addrlen);

  參數:同上

  4、監聽連接——listen()

  功能:用於面向連接服務器,表明它願意接收連接。

  格式:int PASCAL FAR listen(SOCKET s, int backlog);

  5、數據傳輸——send()與recv()

  功能:數據的發送與接收

  格式:int PASCAL FAR send(SOCKET s,const char FAR * buf,int len,int flags);

  int PASCAL FAR recv(SOCKET s,const char FAR * buf,int len,int flags);

  參數:buf:指向存有傳輸數據的緩衝區的指針。 

  6、多路複用——select()

  功能:用來檢測一個或多個套接字狀態。

  格式:int PASCAL FAR select(int nfds,fd_set FAR * readfds,fd_set FAR * writefds, 
fd_set FAR * exceptfds,const struct timeval FAR * timeout);

  參數:readfds:指向要做讀檢測的指針

     writefds:指向要做寫檢測的指針

     exceptfds:指向要檢測是否出錯的指針

     timeout:最大等待時間

  7、關閉套接字——closesocket()

  功能:關閉套接字s

  格式:BOOL PASCAL FAR closesocket(SOCKET s);

 

 

服務器端
socket-->bind-->listen-->accept
客戶端

socket-->connect

vector<int> v(1); cout<<v[1];cout<<v.at[i]

string , vector等的at()成員函數相較下標運算符[]而言,增加了下標越界檢查、異常處理等.   v[1]未定義  v.at[i]拋出異常。

使用快速排序算法對序列9,1,3,8,23,5,7,10,29,19進行排序,基準數取9,則第一趟排序後的結果爲:

7,1,3,8,5,9,23,10,29,19

1、先從後往前搜索小於9的數和9交換得到:   7,1,3,8,23,5,9,10,29,19

2、再從往前搜索大於9的數和9交換得到:    7,1,3,8,9,5,23,10,29,19

3、再從後往前搜索小於9的數和9交換:        7,1,3,8,5,9,10,29,19

while(~scanf("%lld", &n))

~符號是按位取反(是“按位”哦),針對字節變量,把字節中每位取反,相當於和FFH進行異或運算
這裏當沒有輸入的時候,scanf()就返回-1,~-1=0就結束了。

題意:給你一個n,讓你找出一些勾股數組,a^2+b^2=c^2 , 需要滿足a<b<c<=n 。 對於每個case題目首先需要你輸出這些勾股數組中素勾股數T的個數,然後再輸出一個數字,這個數字是n-所有勾股數組用掉的數字個數

思路:本題就是要求在n範圍內的素勾股數,在維基百科內找到相關的資料

 

如果 (abc) 是勾股數,它們的正整數倍數,也是勾股數,即 (nanbnc) 也是勾股數。若果 abc 三者互質(它們的最大公因數是 1),它們就稱爲素勾股數

以下的方法可用來找出勾股數。設 m > n 、 m 和 n 均是正整數,

a = m * m - n * n;

b = 2 * m * n;

c = m * m + n * n;

若 m 和 n 是互質,而且 m 和 n 至少有一個是偶數,計算出來的 abc 就是素勾股數。(若 m 和 n 都是奇數, abc 就會全是偶數,不符合互質。)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
 
const int N = 1000005;
long long n;
int vis[N];
 
long long gcd(long long a, long long b) {
    return b == 0 ? a : gcd(b, a % b);
}
 
int main() {
    while (scanf("%lld", &n) != EOF) {
        int ans1 = 0, ans2 = 0;
        memset(vis, 0, sizeof(vis));
        long long m = sqrt(n + 0.5);
        long long a, b, c;
        for (long long i = 1; i <= m; i++) {
            for (long long j = i + 1; j <= m; j += 2) {
                if (gcd(j, i) == 1) {      
                    a = j * j - i * i; 
                    b = 2 * i * j; 
                    c = i * i + j * j; 
                    if (c <= n) {
                        ans1++; 
                        vis[a] = vis[b] = vis[c] = 1; 
                    }
                    for (int k = 2; c * k <= n; k++)
                        vis [k * a] = vis[k * b] = vis[k * c] = 1;
                } 
            }
        }
        for (int i = 1; i <= n; i++)
            if (vis[i])
                ans2++;
        printf("%d %d\n", ans1++, n - ans2++);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章