رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

فرهاد شیری

مدیران مرجع
  • تعداد ارسال ها

    134
  • تاریخ عضویت

  • روز های برد

    38

آخرین بار برد فرهاد شیری در 22 مرداد

فرهاد شیری یکی از رکورد داران بیشترین تعداد پسند مطالب است !

اعتبار در سایت

146 عالی

3 دنبال کننده

درباره فرهاد شیری

توسعه‌ دهنده بَک اِند
توسعه‌ دهنده فرانت اِند
اساتید
  • تاریخ تولد 20 مهر 1360

موقعیت

  • شهر
    تهران

آخرین بازدید کنندگان نمایه

617 بازدید کننده نمایه
  1. فرهاد شیری

    جناب رمضانی منش به نظرم سوال شما اصلا مبتدی نیست بلکه دقت نظر بالای شما را می رساند! در این کلاس عملگر (=) را مجدد بارگذاری کردم، که باعث می شود در زمان تعریف یک property مقداردهی اولیه را انجام دهد و در صورتی که رشته باشد طول این رشته نیز مقدار دهی می شود. بنابراین در سازنده کلاس هم باید این منطق تکرار شود و به علت اینکه از کد تکراری استفاده نشود عمگر (=) را به این صورت فراخوانی شده است. فراخوانی متدهای عضو کلاس از داخل متدهای عضو که برای فراخوانی عملگرهای بارگذاری شده به این صورت ((-)=operator) فراخوانی می شود. که می توان به این شکل هم نوشت ... explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) { this->operator =(rhs); } OR explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) { ::operator =(rhs); } و دراین قسمت هم اگر در زمان تعریف یک property یک رشته داشته باشیم، جهت اینکه در زمان اجرا به مقدار کلاس string صحیح اشاره کنم به این صورت تبدیل کرده ام. بنابراین به علت اینکه مقدار m_property یک عضو const تعریف شده است، لذا با استفاده از const_cast رفرنس متغیر عضو m_property را از حالت const خارج میکنم و در زمان اجرا به یک اشاره گر *string با استفاده از عملگر reinterpret_cast تبدیل میکنم و در نهایت هم که مقدار اشاره گر را دی رفرنس میکنم و یک رفرنس از کلاس property که به string تبدیل شده را در سازنده به یک متغیر عضو به نام data منتقل میکنم. و البته به این صورت هم می شد نوشت... property_type& get(){ return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property))); } OR property_type& get(){ return *((property_type*)&const_cast<property_type&>(m_property)); } بازهم تشکر میکنم از حسن توجه شما دوست گرامی.
  2. معمولا یکی از چالش های برنامه نویسی شی گراء که همواره بر سر راه برنامه نویسان وجود دارد، Map شدن دیتاهای موجود در بانک های اطلاعاتی در کلاس های model می باشد. به این ترتیب که بتوان داده ها را در فیلدهایی که در کلاسهای مدل که تعریف شده اند را به این داده ها متصل نمود به همین علت بعد از این Map شدن داده ها باید متدهایی جهت یکپارچه سازی داده ها در این کلاسهای model تعریف نمود تا هم بتوان مقادیر این داده ها را بازیابی کرد وهم بتوان به راحتی این داده ها را به روز رسانی نمود. در صورتی که تجربه کار با entity framework ها را داشته باشید، قطعا متوجه شده اید که وقتی داده ها را به Property کلاسهای مدل Map میکنیم به راحتی با خود همین خصیصه های تعریف شده هم عملیات بازیابی را انجام می دهیم و هم به راحتی مقدار های جدید فیلدهای مرتبط به خصیصه راهم به روز رسانی می نماییم، که با این کارهم بازدهی برنامه بالاتر خواهد بود وهم از نوشتن متدهای پردردسر هم راحت میشویم. با ذکر این مقدمه قصد دارم کلاسی را خدمتتان معرفی کنم که جهت تعریف property ها استفاده می شود، البته استفاده از خصیصه ها در entity framework یکی از کاربرد property می باشد. با استفاده از کلاس زیر می توانید انواع مختلف داد های رایج را به صورت خصیصه تعریف کنید و به راحتی بدون نیاز به تعریف متدهای اضافی از این خصیصه ها استفاده نمایید. البته به علت اینکه این خصیصه ها قابلیت تعریف const را دارا می باشند بسیار مناسب پردزاش های چند نخی می باشند. #ifndef PROPERTY_H_ #define PROPERTY_H_ #include "MyException.h" #include "typeinfo" template<typename Tp> struct CProperty{ typedef Tp property_type; private: inline void setLength(property_type& rhs) throw(MyException){ const_cast<size_t&> (length) = (reinterpret_cast<std::string*>(&rhs))->length(); } const property_type m_property; public: /*Preorder: * default constructor is commented! because if * uncommented and create new object from this and no passed * default value property and when compile the program compiler * no sending error but show error in linker program. */ //CProperty(); //Preorder: copy constructor CProperty(const CProperty<property_type>& rhs): m_property(rhs.m_property) ,length(0) ,data(get()) {} //Preorder: copy operator const CProperty& operator=(const CProperty<property_type>& rhs){ const_cast<property_type&>(m_property) = rhs.m_property; return *this; } /*Preorder: * when create new property must pass the default value of * property! */ explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) { operator =(rhs); } //PreOrder: setter method inline void operator=(const property_type& rhs) throw(MyException){ const_cast<property_type&>(m_property) = rhs; if(strcmp(typeid(property_type).name(),"Ss") == 0) setLength(const_cast<property_type&>(rhs)); } //override comapre method in string class inline bool operator==(const property_type& rhs) throw(MyException){ return get().compare(rhs) == 0; } inline bool operator==(const property_type& rhs) const throw(MyException){ return get().compare(rhs) == 0; } operator Tp() { return m_property; } operator Tp() const { return m_property; } //get the value property property_type& get(){ return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property))); } const property_type& get() const { return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property))); } const size_t length; const property_type data; }; typedef struct CProperty<bool> Bool; typedef struct CProperty<int> Int; typedef struct CProperty<std::string> String; #endif /* PROPERTY_H_ */ و به راحتی به روش های زیر هم می توانید از کلاس فوق استفاده کنید. /*define and set new string property in direct mode*/ const String myStr1("test1"); String myStr2("test1"); /*change property value.l*/ //myStr1 = "change test1"; std::cout << "My String 1 property is:(" << myStr1.data << ") and this length is:(" << myStr1.length << ") " << '\n'; std::cout << "My String 2 property is:(" << (string)myStr2 << ") and this length is:(" << myStr2.length << ") " << '\n'; /*comapre two strings*/ if(myStr2 == myStr1) std::cout << "myStr2 and myStr1 is equal!" << '\n'; else std::cout << "myStr2 and myStr1 is not equal!" << '\n'; /*define boolean property*/ Bool bol(false); std::cout << bol << '\n'; Bool bol2(false); std::cout << bol << '\n'; if((bool)bol2 == (bool)bol) std::cout << "bol2 and bol is equal!" << '\n'; else std::cout << "bol2 and bol is not equal!" << '\n'; /*define int property*/ Int myInt(10); //myInt = 20; //change property در صورتی که ابهام وجود داشت بفرمایید. و اگر هم پیشنهادی و یا انتقادی داشته باشید، خوشحال خواهم شد مطرح کنید. موفق باشید
  3. فرهاد شیری

    عرض کردم کلید خصوصی را چطوری مهندسی معکوس میکنه وقتی تقریبا 99/99 درصد امکان نداره که کلید را از روی داده رمز شده بدست آورد چون اصولا برگشت پذیر رمز نشده! حالا چه fiddler چه هر ابزار دیگه برای sniff امکان نداره به این سادگی مجوز های SSL را دور بزنه(که اگر اینطوری بود حتی یک ریال هم نمیتونستیم با اطمینان بین چندتا حساب جابجا کنیم! مطمئن باش دوست عزیز! تا زمانی که ابر کامپیوتر های کوانتومی برای مهندسی معکوس رمزها ساخته نشده اند با ابر کامپیوترهای باینری حتی به صورت پردازش موازی ویا حتی پردازشگرهای توزیع شده هم بازهم تقریبا در خوشبینانه ترین حالت نزدیک 50 سال طول میکشه که یک رمز SSL را بشکنند!) بنابراین با خیال راحت استفاده کن!
  4. اگر دنبال یک نرم افزار قدرتمند برای مشاهده فایلها به صورت Hex هستید، پیشنهاد میکنم از نرم افزار WinHex را حتما نصب کنید. از قابلیتهای فوق العاده این نرم افزار این هست که همانطور که می دانید اگر در نرم افزار VmWare نسخه لینوکسی داشته باشید که دیسک های آن را به صورت VMDK تعریف کرده باشید، وهمچنین اگر فرمت FAT دیسک های لینوکس را هم از نوع Ext3 تعریف کرده باشید ودر صورتی که به هردلیلی نسخه لینوکس را از دست بدید ونتوانید آن را بازیابی کنید! دیگه به راحتی نمیتوانید این دیسک ها را در سیستم عامل میزبان خود بازیابی کنید. اما با استفاده از نرم افزار WinHex می توانید فایلهای دیسک VMDK خودتون را باز کنید و به فایلهای لینوکس تون دسترسی داشته باشید، این چالش بدترین کابوس ما برنامه نویسانی هست که در لینوکس کد میزنیم از دست دادن این سورس کدها واقعا استرس زیادی به آدم وارد میکنه! همانطور که در تصویر هم مشاهده میکنید من برای لینوکس خودم همین اتفاق افتاد که تونستم به این روش سورس کدهای تحت لینوکس ام را بازیابی کنم (البته قبلش یکی دوتا کار دیگه باید انجام بدید تا WinHex فایل دیک را براتون باز کنه! اگر کسی علاقمند بود اطلاع بدید تا اون راه ها را هم توضیح بدم)
  5. در بعضی از پروژه های تجاری نیاز هست که به لاگ فایل ها ویا اطلاعاتی که در یک ماشین راه دور دریک سیستم عامل مانند لینوکس که در یک کانال خاص با میزبان شما در ارتباط می باشد، دسترسی داشته باشید واین لاگ فایل ها ویا اطلاعات را در یک پایگاه داده ذخیره کنید، البته بیشتر هدف این است که سیستم عامل های لینوکسی که در مد kernel کار میکنند و به علت های زیادی امکان استفاده از پایگاه داده را ندارند به همین علت باید این اطلاعات را برای یک ماشین میزبان ارسال کنیم و درآنجا دریک Data Where House ذخیره کنیم.! برای این کار می توانید از نرم افزار قدرتمند Kiwi SysLog Service استفاده کنید!
  6. فرهاد شیری

    وقتی صحبت از SSL میکنید که قطعا به این سادگی ها فقط با یکسری ابزار sniff و network packet analyzer مثل WireShark که نمی توان داده ها را تغییر داد! به فرض که شما به اون پکت های درست هم دسترسی پیدا کردید چطوری میخواهید بدون استفاده از کلید اختصاصی SSL رمزگشائی کنید، از روی داده رمزشده هم امکان استخراج کلید اصلی تقریبا محال ممکن هست! پس امنیت SSL به این راحتی ها قابل شکستن نیست ودرضمن مجوز جعلی هم برای SSL نمی توان ساخت که بخواهید ازش استفاده کنند. در ثانی این ابزاری که شما می فرمایید معمولا برای استفاده در ابزارهای تست نفوذ استفاده می شوند، به این صورت که سیستم های تست نفوذ الگوریتم های هوش مصنوعی هستند و برای train کردن این نرم افزارها نیاز به داده هایی دارند که براساس نوع پکت های شبکه نفوذهای انجام گرفته را بررسی کنند، حالا ابزارهایی مثل WireShark چنین خروجی هایی را تولید میکنند البته اونهم به صورت هگز.
  7. فرهاد شیری

    والبته توجه داشته باشید که در SDK های پایینتر از 24 نحوه اجازه دسترسی به محتواها با SDK های بالاتر از 24 متفاوت می باشد، یعنی در SDK های قدیمی نیازی نبود که شما دسترسی ها را در اکتیویتی هندل کنید ولی در SDK های جدید حتما باید برنامه نویس متدهای لازم برای تعیین دسترسی ها را در اکتیویتی اصلی Override کنه! بنابراین اگر این پروسه دریافت دسترسی از کاربر را به درستی انجام نداده باشید، بعد از اینکه به اکتیویتی برگردید با خطا مواجه می شوید. برای مشاهده خطا از log اندروید استفاده کنید در صورتی که موفق نبود یکبار User Debug Mode انجام بدید ویک break Point در سورس کد در نقطه مورد نظر قرار بدید تا خطا را شناسایی کنید. در صورتی که بازهم دلیل منطقی پیدا نکردید بهتر Kernel Debug Mode را انجا بدید کافی که از خروجی پردازشگر و همچنین از رم گوشی در هنگام اجرای برنامه خودتون یک فایل Dump تهیه کنید وبا ابزار eclipse memory analyzer فایل مورد نظر را بررسی نمایید.
  8. فرهاد شیری

    می توانید با کد زیر تست کنید که دسترسی های لازم وجود داره یا نه! و عملکرد مناسب را انجام بدید.! auto result = QtAndroid::checkPermission(QString("android.permission.CAMERA")); if(result == QtAndroid::PermissionResult::Denied){ QtAndroid::PermissionResultMap resultHash = QtAndroid::requestPermissionsSync(QStringList({"android.permission.CAMERA"})); if(resultHash["android.permission.CAMERA"] == QtAndroid::PermissionResult::Denied) return 0; resultHash = QtAndroid::requestPermissionsSync(QStringList({"android.permission.READ_EXTERNAL_STORAGE"})); if(resultHash["android.permission.READ_EXTERNAL_STORAGE"] == QtAndroid::PermissionResult::Denied) return 0; resultHash = QtAndroid::requestPermissionsSync(QStringList({"android.permission.WRITE_EXTERNAL_STORAGE"})); if(resultHash["android.permission.WRITE_EXTERNAL_STORAGE"] == QtAndroid::PermissionResult::Denied) return 0; } حالا وقتی این تکه کدها را اجرا بشوند، منتظر دریافت اجازه دسترسی از کاربر خواهد بود در صورت عدم تایید دسترسی به محتوا مربوطه مقدار Denied ارسال میشود!(توجه هم داشته باشید که این توابع به صورت سنکرون هستند یعنی نخ اصلی منتظر تایید کاربر برای دسترسی خواهد بود تا روند اجرا برنامه ادامه یپدا کند! از این منبع هم می توانید برایاطلاعات بیشتر استفاده نمایید.( QtAndroid Namespace)
  9. فرهاد شیری

    دوست گرامی! اگر منظورتون استفاده از پلتفرم هایی مثل کیوت که توانایی ایجاد خروجی اندروید هم دارند که می توان بازبان ++C هم برای این پلت فرم برنامه نوشت، هست که باید عرض کنم هرچند قبلا خیلی بحث شده! ولی اینکه Qt,QML را یاد بگیرید خیلی از مباحث اندروید را هم یاد میگیرید باید عرض کنم خیر! حالا چرا به این علت که اغلب این فریم وورک هایی که توانایی خروجی دادن اندروید را هم دارن خودشون مستقل از اندروید یک تفسیر کننده دارند! مثلا برای همین کیوت شما کلا با مفاهیم Activity , Fragment ,... برای ایجاد GUI های تعامل با کاربران کاری نخواهید داشت بلکه زبان مستقلی به نام QML را باید یاد بگیرید واز اون استفاده کنید. والبته خیلی بحث های دیگه .... بنابراین خیلی خوب که پارالل هم اندروید جاوا را یاد یگیرید وهم پلت فرم Qt, QML را یاد بگیرید. البته پیشنهاد میکنم حتما کتاب آموزش Qt جناب اسدزاده را تهیه کنید، کتاب آموزش پیشرفته ++C همراه Qt (پیشرفته) 1.3.7
  10. دقیقا چه بخشی را متوجه نمیشید؟ هر Content Provider می تونه متد های مختلفی برای insert داشته باشه! سوال شما مبهمه در ضمن بهتره کمی درباره Content Provider ها مطالعه داشته باشید اغلب سوالات خودتون را پیدا میکنید!
  11. یک Content Provider ارائه دهنده محتوا داده ها از یک برنامه به برنامه های دیگر بر اساس درخواست عرضه میکنه! معمولا چنین درخواست هایی توسط کلاس ContentResolver انجام می شود. یک ارائه دهنده محتوا می تواند از روش های مختلف برای ذخیره داده های خود استفاده کند و داده ها را می توان در پایگاه دادهSQLlite، فایل ها یا حتی در وب سرویس ها ذخیره کرد. اگر بخوام بهتر توضیح بدم اینطور بگم در سیستم عامل ویندوز که ابزارهای مختلفی برای ذخیره سازی داده ها وجود دارد مانند SQL Server , Oracle ,Access,Excel,... بنابراین محل های ذخیره سازی زیادی داریم که بنا بر استراتژی نرم افزارهای خودمون از یکی از این ابزارها ویا از چنتاشون باهم استفاده میکنیم خوب حالا ویندوز برای اینکه تمامی این ابزارها با هم سینک باشن و بتونیم به راحتی باهشون ارتباط برقرار کنیم ابزارهایی مثل ODBC,ADO,ADO.NET,.... را تدارک دیده که دقیقا همون کاری را میکنن که Content Provider ها در اندروید انجام میدن! به این آموزش هم مطالعه کنید یک مثال ساده هم وجود داره! - Android - Content Providers
  12. فرهاد شیری

    نه آقا چه حرفی! برخوردن دیگه چی!(من نمیدونم این بدعت کی گذاشته که ماهرچی بگیم منتج به این حرف میشه! شما فرمودید که توجه نکردید، منهم عرض کردم که متوجه اون مثال شدم. این کجاش برخوردنه میخواهید یک قالب درست کنید توسایت که طبق همون جواب سوالها را بدیم اگر برمیخورد که نمیخندیدم اتفاقا نه تنها برنخورد بلکه برام جالب بود که اصولا دست به پیچوندن خوب دارید ماگفتیم مثال برای کاری که انجام دادید بذار شما اومدی میگی گذاشتم توجه نکردید دوست عزیز حال نداری مثال بذاری چرا توپ میندازی زمین ما... تشکر بابت توضیحی که دادید. قطعا من اگر میخواستم استفاده کنم همین مثالی که مربوط به خود مفسر اسکریپت بود، معرفی کردید ازش استفاده میکردم، ولی من گفتم مثال برای کسانی که شاید نتونن به خوبی ازش استفاده کنن کمی قابل درکتر و راحت بشه! دوست گرامی! من ناراحت نشدم ولی به هرحال تشکر از حسن لطف شما
  13. و البته زمانی که از نخ ها مانند AsyncTask استفاده میکنید و عملیاتهای مختلف I/O انجام میدید بهتره که از همه اکسپشن ها را در یک Try ارسال نکنید و همچنین از یک خاصیت به نام autoclose هم می توانید برای کلاسهای جاوا استفاده کنید که نیازی به نوشتن متد close برای هر کلاس ورودی و خروجی نداشته باشید. مثال ویرایش شده... @Override protected String doInBackground(String... params) { try(URL url=new URL("http://s8.picofile.com/d/8349389850/06c69ac4-70fb-4d33-991f-ac01b8c5324f/b.mp3")){ URLConnection connection=url.openConnection(); connection.connect(); try( InputStream fis=new BufferedInputStream(url.openStream(),10*1024)){ try(FileOutputStream fos=new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/saeed.mp3")){ int c=0; byte[] d=new byte[1024]; while ((c=fis.read(d))!=-1){ fos.write(d,0,c); } fos.flush(); } catch (IOException expOutPutStream) { expOutPutStream.printStackTrace(); } } catch (IOException expInputStream) { expInputStream.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } return null; }
  14. فرهاد شیری

    قطعا دقت کردم ظاهرا شما دقت نکردید که اون مثال مربوط به پست شما نیست ! انشاالله اگر بی دقت نباشیم!! منظورمون از مثال برای این پست بود...
  15. کلاس بافر یک Wrapper برای کلاس InputStream هست که امکان استفاده از یک بافر داخلی(آرایه داخلی) را به شما میده که میتونه سرعت بهتری نسبت به کلاس Base به شما بده! و اینکه چه مقادیری برای استریم های ارسالی و دریافتی تعیین میکنید بسته به شرایط ونوع فایل ها متفاوت هست! مثلا وقتی در کلاس بافر سایز تعریف میکنید باید به این نکته توجه کنید که درصورتی که یک بایت را بخواهید شیفت بدید کلاس بافر میاد از کلاس Array.copy استفاده میکنه وتمام بایت ها را دوباره مینویسه بنابراین در صورتی که این مقادیر را بیش از اندازه بزرگ تعریف کنید هزینه ی زیادی براتون داره در مصرف منابع حافظه. ویا وقتی یک آرایه از بایت ها تعریف میکنید بهتر هست که کمترین سایز ممکن را تعریف کنید که در صورتی که به هردلیل مشکلی در آرایه بایت ها به وجود آمد هزینه کمتری بابت از دست رفتن منابع بدهید به همین علت است که معمولا فایلهای خیلی بزرگ را در نخ های Background دانلود میکنن ونه در نخ اصلی ودریکبار بافر کردن داده ها. استریم بایت ها را به صورت بسته های خیلی کوچک در یک نخ کاربری background دریافت میکنن و در زمان مناسب همه بایت ها را به هم وصل میکنن! توجه داشته باشید که برنامه نویسی در زبانهای جاوا و دات نت اتلاف منابع حافظه ای زیادی میتونه در بر داشته باشه بنابراین باید همیشه به این نکات توجه داشته باشید. پیشنهاد میکنم این مطالب راهم مطالعه کنید! 10 تکنیک کاربردی که باعث بهینه شدن عملکرد برنامه های جاوا می شود
×
×
  • جدید...