Страницы

Поиск по вопросам

среда, 3 октября 2018 г.

Определить уровень RSSI в WEB

Есть ли способы определить уровень сигнала RSSI Wi-Fi точки в WEB? Например с помощью JavaScript.
Нужно, чтобы при заходе на web-страницу с мобильного устройства отображался уровень сигнала RSSI до той WI-FI точки, к которой подключено это мобильное устройство.
Топология:
UPD: (08.07.2015)
Вот чего смог добиться!


Ответ

Вы никак не сможете узнать исключительно через JavaScript RSSI/SNR учтенный собственно клиентским устройством - стандартных методов для этого разработчиками браузеров не предусмотренно.
Однако вы можете показывать клиенту его же RSSI/SNR, учтенные самой точкой доступа, если она поддерживает мониторинг этих данных каким-либо образом.. Многие Cisco и Mikrotik'и умеют выдавать их посредством SNMP. Про точки доступа других фирм я не знаю.
Достаточно поднять веб-сервер, и на нем развернуть небольшое веб-приложение, которое будет опрашивать точку к которой подключен клиент, выбирать данные по конкретно этому клиенту, и отдавать их обратно клиенту в виде JSON-ответа, например. Ну а дальше - обращатся с клиента к этому веб-серверу через AJAX, и отображать полученные значения где необходимо.
Если для авторизации используется RADIUS, то информацию о клиенте и точке доступа к которой он подключен можно вытащить c RADIUS-сервера.
Если же авторизация не используется, либо используется WEP/WPA/WPA2, то для получения информации о клиенте и точке доступа, вы можете использовать клиентский IP и MAC - если веб-сервер и точки доступа находятся в пределах одной сети на коммутаторах, то MAC-адрес полученный веб-сервером всегда будет идентифицировать точку доступа к которой клиент подключен, а IP - непосредственно клиента на ней.

emplace_back для int

‒ Ты понимаешь, что происходит? ‒ Тебе объяснить? ‒ Объяснить я и сам могу... Ты понимаешь или нет?
Простите за эпиграф, но... Что-то у меня ощущение, что я могу объяснить, но не понимаю (или наоборот...), что происходит вот тут:
std::vector v; v.emplace_back(1); v.emplace_back({1}); v.emplace_back(int{1});
Как стандарт трактует эти три выражения, и почему такой странный диагноз
emplace_back: функция не принимает 1 аргументов
у средней строки?


Ответ

Для этого предложения
v.emplace_back({1});
проблема состоит в том, что когда используются шаблонные параметры, то не выводится тип шаблонного параметра из заключенного в фигурные скобки аргумента. А функция emplace_back использует шаблонные параметы.
Из стандарта C++ (14.8.2.1 Deducing template arguments from a function call)
1 Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers from P gives std::initializer_list for some P0 and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P0 as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context
Можно смоделировать такую же ошибку следующим примером объявления класса
#include #include
struct A { template void f( T &&... ) const {} };
int main() { A().f( { 1 } );
return 0; }
Компилятор может выдать следующее диагностическое сообщение
prog.cpp: In function 'int main()': prog.cpp:13:15: error: no matching function for call to 'A::f()' A().f( { 1 } ); ^ prog.cpp:8:7: note: candidate: void A::f(T&& ...) const [with T = {}] void f( T &&... ) const {} ^ prog.cpp:8:7: note: candidate expects 0 arguments, 1 provided
Если вы замените emplace_back на нешаблонный метод push_back , то соответствующий вызов будет компилироваться, так как тип параметра функции известен из типа объявленного инстанциированного вектора и представляет собой тип int
Поэтому вам явно нужно будет указать тип шаблонного аргумента функции
Например,
#include #include
struct A { template void f( T &&... ) const {} };
int main() { A().f( { 1 } );
return 0; }
Или для emplace_back
#include #include #include
int main() { std::vector v;
v.emplace_back( { 1 } );
for ( int x : v ) std::cout << x << ' '; std::cout << std::endl;
return 0; }
Вывод программы на консоль
1
или для примера, предложенного @alexolut в комментарии
#include #include
struct S { S(std::initializer_list) {} };
int main() { std::vector v; v.emplace_back>({1}); }
Что касается выражения в данном вызове
v.emplace_back(int{1});
то здесь используется явное преобразование типов, так называемая функциональная нотация.
Из стандарта C++ (5.2.3 Explicit type conversion (functional notation))
3 Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list, and its value is that temporary object as a prvalue.

RestKit: за и против

Хотелось бы узнать мнение коллег о библиотеке RestKit
Интересует именно реальный опыт использования библиотеки, а не ссылки на проект на Гитхабе или документацию: я уже достаточно хорошо ознакомился с документацией и прочитал несколько постов автора библиотеки на SO (особенно содержательным оказался этот).
После просмотра всего материала по RestKit наиболее ценным кодом в библиотеке мне показался код, т.н. Object Mappings Engine, решающий задачу автоматического связывания JSON-объектов с моделями Core Data на основе автоматического распознавания типов свойств соответствующих объектов:
RestKit leverages the highly dynamic Objective-C runtime to infer the developers desired intent by examining the type of the source and destination properties and performing appropriate type transformations.
...что выглядит очень привлекательной возможностью для того, чтобы перестать создавать большие объёмы соответствующего кода руками и положиться на, наверное, второй по популярности после AFNetworking проект на Objective-C среди проектов, связанных с Networking и REST с огромной коммунити и активностью. Как минимум, возникает соблазн выкрасть Mapping Engine, - я рассматваю такой вариант, так как очень комфортно себя чувствую со всеми остальными участниками этой схемы: AFNetworking, Core Data, Concurrency (GCD + NSOperation + Threads)
Очень интересен ваш опыт, особенно интересны граничные случаи (например, пришлось отказаться от Restkit потому-то и тому-то, или, наоборот, случаи вроде "RestKit спас нас от верной гибели на долгие годы вперёд") и особенно интересны случаи употребления RestKit в сложных проектах (много сетевого взаимодействия, разнообразие данных и пр.).
Спасибо.
P.S. Интересно услышать персональное мнение @AlexDenisov, он явно в курсе ;)
ОБНОВЛЕНО ПОЗЖЕ
Несмотря на то, что в этом топике уже есть принятый ответ, я буду рад любым другим ответам, описывающим реальный опыт использования RestKit. Спасибо.


Ответ

Я очень давно заметил RestKit, когда он еще был 0.10.х-ой версии, но использовать его в реальном проекте удалось только около полугода назад, фактически это был мой первый опыт, довольно печальный. Около полутора месяцев назад я начал работу над новым проектом, и там я использую RK, это мой второй опыт, печали гораздо меньше. tl;dr RestKit очень крут и удобен при условии что у вас действительно RESTful API. Как и во всем ПО в нем есть баги, причем порой очень необычные. Опыт первый Новый проект, пришел ПМ и сказал "Пишите спеки на API, ребята будут делать". Радости было немеряно. На спеки мы командой из трех человек потратили два дня. Спеки были готовы, RESTful, все дела. После я начал писать тесты на апиху на стабах, писал дня три, был безумно счастлив. И тут постепенно начали появляться первые endpoint'ы на серваке, причем апиха полностью не соответствовала тому что мы описали в спеках. Вместо одного ресурса с GET/POST/etc было 4: getProducts, createProduct, etc... Выпиливать RK я не решился, и стал адаптировать его под реальную апишку, здесь я и столкнулся с главным его минусом: оно работает идеально если у вас действительно RESTful API (собственно по этой причине я и не мог им пользоваться столь долгое время). В принципе он сработал и в нашем случае, но это был оверхед: пришлось описывать descriptor'ы по несколько раз для разных путей одной сущности. Да и тесты пришлось выкинуть, потому что их поддержка с таким API была очень трудоемкой задачей. Опыт второй Новый проект, рядом ребята которые пишут API, чистейший RESTful API. Поначалу даже с ровным рестом казалось что есть некий оверхед, потому как первые дни писл много кода для маппингов, роутов и дескрипторов, но спустя почти месяц когда все апи описано работа с сетью стала просто удовольствием, буквально три строчки - и все, ждем наши модели или ошибки (которые тоже очень удобно мапятся в модели). Из минусов: внезапно столкнулся с проблемой, сначала были мысли переписать апишку, пока не укатилось на прод, но я решил подождать и начал искать проблему. Решение меня очень удивило: по факту я изменил довольно серьезную часть кода, но ни один тест не свалился. В итоге все еще жду, возможно таки прийдется переписать этот кусок апихи, чтоб не таскаться с патченой версией. P.S. извиняюсь за столь большой объем и сумбурность изложения UPD Повторные запросы Особо с такой темой не сталкивался, единственная похожая ситуация: шлем запрос на авторизованный ресурс, в ответ приходит 401 Unauthorized, шлем логин/пасс на сервер, получаем токен и повторно шлем первый запрос. Честно говоря есть ли такая возможность у RK я не знаю, но мой коллега обрабатывал этот кейс простым образом: если где-то приходит 401, то обработка уходит в другую ветку, где и выполняются все эти запросы. Единственные "грабли" в этом решении в том, что приходится создавать новый RKRequestOperation (т.к. старый является закешированным, и повторно его послать не получится) и самому отправлять его в очередь (enqueueRequestOperation:). А в целом нужно внимательно посмотреть доки/исходники, я еще не успел столкнутся с такой задачей :)

Обязательно ли NULL в Си является указателем?

Вопрос на основе обсуждения ответа про sizeof NULL
Вот куски стандарта:
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant NULL which expands to an implementation-defined null pointer constant
Кажется, что не запрещено вместо #define NULL ((void*)0) сделать просто #define NULL 0, как это сделано в плюсах. Тогда получается, что sizeof NULL равен либо sizeof (void*), либо sizeof (int) (в варианте sizeof 0).
Однако, @Vlad from Moscow утверждает, что NULL в Си обязан быть указателем.
NULL в С определен как указатель. Ключевое значение в приведенной цитате имеют слова "cast to type void *". Здесь или имеет отношение не к приведению типов, а к виду выражения. И именно таким образом определяется NULL.
Так допустимо ли для Си (без плюсов) иметь?
#define NULL 0
И если допустимо, то почему в компиляторах используется
#ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif
вместо более простого варианта с нулём для обоих языков? Ведь в си даже перегрузки функций не было, чтобы можно было что-то сломать.


Ответ

Просмотрев внимательно стандарт C, я думаю, что вы правы. null pointer constant - это либо целочисленное константное выражение со значением 0, либо такое выражение, приведенное к типу void *
Поэтому определение макроса NULL может быть в принципе различным, зависящим от реализации компилятора. То есть нигде в стандарте C я не нашел, что макрос NULL обязан быть определен как
( void *)0
Я заглянул в документ Rationale for International Standard— Programming Languages— C и там нашел следующее (7.17 Common definitions )
25 NULL can be defined as any null pointer constant. Thus existing code can retain definitions of NULL as 0 or 0L, but an implementation may also choose to define it as (void*)0. This latter form of definition is convenient on architectures where sizeof(void*) does not equal the size of any integer type.
Так как null pointer constant преобразуется в выражениях в null pointer, а размер null pointer может быть не равен размеру ни одному целочисленному типу, то удобнее определять null pointer constant как
( void * )0
то есть сразу же приводить ее к типу указателя.
В C++ от такого определения отказались, так как в отличии от C в C++ в связи с обеспечением безопасности типов нужно явное приведение указателя на void к типу указателя на конкретный объект. То есть если null pointer constant NULL будет определена в C++ как
( void *)0
то вам придется делать явное приведение указателей, как, например,
int *p = ( int * )( void *)0;
что, естественно, очень обременительно.
Поэтому в C++ Отказались объявлять NULL в виде целочисленной константы, приведенной к типу void *

Что значит “комбинированный алгоритм для её обслуживания”?

Задание. Необходимо реализовать очередь на базе списков, применяя комбинированный алгоритм для ее обслуживания. Затем продемонстрировать выполнение основных операций с элементами очереди: поиск, добавление, удаление.
Необходим некоторый пример для ясности как реализовать список используя комбинированный алгоритм обслуживания.


Ответ

Мне кажется, что, в данном случае, имеется в виду, что надо использовать несколько алгоритмов, например для поиска:
Class list { function search(element) { if(this.size > 100){ //ищем делением пополам например исходя из того что при добавлении мы храним отсортированный массив } else { //ищем простым перебором т.к. для малого количества это будет быстре } } //аналогично для добавления, удаления, используем разное поведение в зависимости от контекста }

Как правильно: перегрузка или переопределение?

В одних статьях пишут перегрузка, в других пишут переопределение. Тоже самое с наследниками и производными. По смыслу это одно и то же, но как правильно:
перегрузка или переопределение? в наследниках или в производных?
Чтобы далеко не ходить за примерами я стал искать прямо на сайте ответы по интересующим меня методам Equals и OnModelCreating, которые описаны в документации как виртуальные, и нашел следующие ответы:
"следует перегрузить метод OnModelCreating - и написать там примерно следующее" 27 май '15 в 15:53, Pavel Mayorov, 9,255 "базовый класс всех типов-значений, перегружает метод Equals" 30 сен '15 в 0:01, VladD, 74k "Переопределите Equals так, чтобы он сравнивал два экземпляра" 23 дек '15 в 8:52, PashaPash, 20.1k
Из контекста следует, что в ответах говорят о виртуальных методах. Получается, что перегрузка и переопределение - это одно и тоже. Хотелось бы понять как правильно: перегрузка или переопределение?
UPD: (2/10/2016 8:52 PM)
Перегрузка и переопределение, как сказал rdom: это абсолютно разные вещи VladD внес исправления в свой ответ. Ошибки в других ответах, надеюсь, также будут исправлены.


Ответ

перегрузка или переопределение?
По смыслу - это абсолютно разные вещи.
Перегрузка (Overloading) - это возможность использовать одинаковые имена в пределах одного класса у методов сходных по своей сути, но не реализации,за счет расширения понятия имени метода до сигнатуры. Подробнее в соседнем вопросе
Переопределение (Overriding) - относится к виртуальным и абстрактным методам. Это возможность замены виртуального или реализация абстрактного наследуемого метода базового класса методом производного класса.
Пример:
class A { virtual void SomeMethod(int par1, double par2) { }
//Делаем перегруженный вариант метода для другого набора параметров void SomeMethod(double par1, int par2) {} }
class B : A { //Переопределяем унаследованный виртуальный метод override void SomeMethod(int par1, double par2) { } }
UPD
в наследниках или в производных?
тут разночтений нет. Производный класс, класс наследник, а также принятые в Java суб-класс или подкласс, являются синонимами. Также синонимами являются базовый класс, класс предок, супер-класс(java) и над-класс(java).
Дабы не плодить споры: я использую перевод принятый в MSDN. В различных источниках могут использоваться другие варианты перевода. В любом случае, первичным остается смысл оригинальных терминов на английском.

Что значит “->” в Java?

Изучаю данный туториал. На некоторых скриншотах есть конструкция ->, например:
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", res -> { if (res.succeeded()) { System.out.println("Deployment id is: " + res.result()); } else { System.out.println("Deployment failed!"); } });
Не сталкивался раньше с таким. Подскажите, пожалуйста, что это такое и где можно об этом почитать хорошие материалы.


Ответ

Это лямбда выражение - анонимная функция. Проще говоря, это метод без объявления (без модификаторов доступа, возвращающие значение и имя).
Появились в 8 версии Java.
Пример использования
Напишем простой пример функционального интерфейса :
public interface Lambda { //Метод интерфейса с отсутсвующей реализацией int getDoubleValue(int val);
//Метод интерфейса с реализацией по-умолчанию default void printVal(int val) { System.out.println(val); } }
Функциональный интерфейс должен иметь только один абстрактный метод. Прочитать о причинах такого ограничения можно здесь
Теперь создадим класс для использования
public class ClassForLambda { public static void main(String[] args) { //Объявляем ссылку на функциональный интерфейс Lambda lam; //Параметр для нашего абстрактногго метода int num =9;
//Прописываем первый вариант реализации lam = (val) -> val * 2; System.out.println(lam.getDoubleValue(num));
//Прописываем второй вариант реализации lam = (val) -> { System.out.println("Your number is "+val); return val * 2; }; System.out.println(lam.getDoubleValue(num)); } }
Как можно заметить, обращение к методу не изменилось. Изменению подверглась только реализация.
Ссылки:
Хабр JavaRush Еще один ответ на StackOverflow