Dengan latar belakang diskusi yang menggelegar di sini di Habré tentang teka-teki algoritmik dan wawancara di Yandex, saya ingat bagaimana salah satu teman saya, yang bekerja untuk satu perusahaan (non-Rusia) yang agak besar, pernah menawari saya masalah dari wawancara yang mereka lakukan. Sekarang masalahnya telah berubah (mereka menemukan contoh kode yang lebih keren), jadi dengan izinnya, saya menerbitkan versi lama di sini.
Kandidat yang menduduki posisi pengembang tidak diberikan masalah algoritmik, tidak didorong melalui belantara bahasa, tetapi hanya diberi kode untuk ditinjau. Kode dari proyek nyata yang pernah mencoba membekukan seorang junior hijau. Untungnya, mereka menyadarinya tepat waktu.
Disarankan untuk melakukan hal berikut:
Periksa kode tersebut dan tebak secara singkat apa fungsinya. (semuanya didokumentasikan dengan cukup baik dalam proyek, tetapi perpustakaan pihak ketiga dengan dokumentasi dan komentar terkadang mengalami masalah, dan pengembang harus memahami apa yang terjadi di sana)
Lakukan peninjauan kode, tunjukkan tempat-tempat yang mencurigakan dan buruk, dan sarankan bagaimana tempat itu dapat diperbaiki atau diperbaiki. Anda dapat mengajukan pertanyaan apa pun dan mencari di Google apa pun yang Anda inginkan.
Kode ada dalam C ++, meskipun sebagian besar bug dapat ditemukan bahkan oleh pengembang dalam bahasa lain. Kodenya kira-kira seperti ini:
class SomeBusServiceClient {
public:
SomeBusServiceClient();
virtual ~SomeBusServiceClient();
bool CallAsync(const std::string &uri, const std::string ¶m,
const misc::BusServiceClient::ResponseCB &callback);
bool CallSync(const std::string &uri, const std::string ¶m,
const misc::BusServiceClient::ResponseCB &callback);
private:
misc::BusServiceClient ss_client_;
static const int kSleepMs = 100;
static const int kSleepCountMax = 50;
};
class SpecificUrlFetcher : public UrlFetcher {
public:
SpecificUrlFetcher();
virtual ~SpecificUrlFetcher();
SomeData FetchData(const URL &url, const UrlFetcher::ResponseCB &callback);
private:
bool SsResponse_returnValue{false};
char SsResponse_url[1024];
void SsResponseCallback(const std::string &response);
SomeServiceClient *ss_client_;
};
// ...
static const char ss_getlocalfile_uri[] = "bus://url_replace_service";
namespace net {
pthread_mutex_t g_url_change_callback_lock = PTHREAD_MUTEX_INITIALIZER;
SomeBusServiceClient::SomeBusServiceClient()
: ss_client_(misc::BusServiceClient::PrivateBus) {}
SomeBusServiceClient::~SomeBusServiceClient() {}
bool SomeBusServiceClient::CallAsync(
const std::string &uri, const std::string ¶m,
const misc::BusServiceClient::ResponseCB &callback) {
bool bRet;
bRet = ss_client_.callASync(uri, param, callback);
return bRet;
}
bool SomeBusServiceClient::CallSync(
const std::string &uri, const std::string ¶m,
const misc::BusServiceClient::ResponseCB &callback) {
boold bRet bRet = false;
int counter;
pthread_mutex_lock(&g_url_change_callback_lock);
ss_client_.callASync(uri, param, callback);
counter = 0;
for (;;) {
int r = pthread_mutex_trylock(&g_url_change_callback_lock);
if (r == 0) {
bRet = true;
pthread_mutex_unlock(&g_url_change_callback_lock);
} else if (r == EBUSY) {
usleep(kSleepMs);
counter++;
if (counter >= kSleepCountMax) {
pthread_mutex_unlock(&g_url_change_callback_lock);
break;
} else
continue;
}
break;
}
return bRet;
}
/**************************************************************************/
SpecificUrlFetcher::SpecificUrlFetcher() {}
SpecificUrlFetcher::~SpecificUrlFetcher() {}
void SpecificUrlFetcher::SsResponseCallback(const std::string &response) {
std::unique_ptr<lib::Value> value(lib::JSONReader::Read(response));
if (!value.get() || !value->is_dict()) {
pthread_mutex_unlock(&g_url_change_callback_lock);
return;
}
lib::DictionaryValue *response_data =
static_cast<lib::DictionaryValue *>(value.get());
bool returnValue;
if (!response_data->GetBoolean("returnValue", &returnValue) || !returnValue) {
pthread_mutex_unlock(&g_url_change_callback_lock);
return;
}
std::string url;
if (!response_data->GetString("url", &url)) {
pthread_mutex_unlock(&g_url_change_callback_lock);
return;
}
SsResponse_returnValue = true;
size_t array_sz = arraysize(SsResponse_url);
strncpy(SsResponse_url, url.c_str(), array_sz);
SsResponse_url[array_sz - 1] = 0;
pthread_mutex_unlock(&g_url_change_callback_lock);
}
SomeData SpecificUrlFetcher::FetchData(const URL &url,
const UrlFetcher::ResponseCB &callback) {
lib::DictionaryValue dictionary;
std::string ss_request_payload;
misc::BusServiceClient::ResponseCB response_cb =
lib::Bind(&SpecificUrlFetcher::SsResponseCallback, this);
SomeBusServiceClient *ss_client_ = new SomeBusServiceClient();
dictionary.SetString("url", url.to_string());
lib::JSONWriter::Write(dictionary, &ss_request_payload);
SsResponse_returnValue = false;
SsResponse_url[0] = 0x00;
ss_client_->CallSync(ss_getlocalfile_uri, ss_request_payload, response_cb);
URL new_url;
if (SsResponse_returnValue) {
new_url = URL::from_string(SsResponse_url);
}
delete ss_client_;
return UrlFetcher::FetchData(new_url, callback);
}
} // namespace net
, , .
, .
- UrlFetcher, , -- - - URL'. , - - , URL, URL, . Decorator.
:
1. ss_getlocalfile_uri - . ? .
2. , . .
3. , SsResponse_returnValue
-:
4. pthread-, std::thread, .
5. - strncpy(); std::string - .
6. ss_client_ . std::unique_ptr.
7. usleep() - std::this_thread::sleep()
:
8. SomeBusServiceClient::CallSync kSleepMs kSleepCountMax, . .
:
9. message bus . . , message bus, - , kSleepCountMax*kSleepMs, , - ( callASync - id ?). - , , URL, .
9. FetchData , new_url , .
10. FetchUrl, , . , , -- WTF? ? , ?
11. ( FetchUrl ), SsResponseCallback . , , . pthread undefined behavior.
12. Catatan berharga dari @snizovtsev : "... Anda tidak dapat menggunakan primitif sinkronisasi ini untuk tugas semacam itu. Jika waktu habis, buka kunci akan dipanggil 2 kali. Artinya, kode salah pada tingkat algoritme dan Anda perlu untuk menulis ulang semuanya menjadi variabel kondisi "
Jawaban dan komentar dari kandidat memungkinkan kami untuk mendapatkan gambaran tentang tingkat pengetahuannya tentang standar C ++ modern dan praktik yang baik, pemahaman tentang asinkron dan multithreading, ketelitian dalam ulasan dan kemampuan untuk "men-debug" kode di kepala. Nah, dan tetapkan topik untuk percakapan lebih lanjut dari hati ke hati.