mishafurman: (Default)

Я понял что мне напоминает работа в большой компании: службу в армии. Хотя я по настоящему в армии не служил - так, два месяца лагерей, занятия на военной кафедре - но это, плюс чьи-то рассказы, книги представление дают. И главное здесь не в том, что особенно выпирает в советской/русской армии - издевательства, дедовщина. И даже не откровенный идиотизм
(как у Гашека) - по крайней мере здесь, в Америке, этого немного. А безликая, многоэтажная, часто бесформенная система управления.

Часто не знаешь, что будешь делать завтра. Иногда и принцип "солдат спит, служба идет" работает. Часто знаешь, что что-то
(иногда и почти все) неправильно, а сделать почти ничего нельзя - потому что слишком много людей, включая начальство, в 
это вовлечены.... В маленькой компании меня однажды выгнали за то, что я сделал нечно за пару месяцев вместо планирумых пары лет, да и несклько по другому. А здесь, такое, наверное почти никто и не заметит...

Но - и плюсы. При чем я не о очевидном развращающем плюсе - хорошей зарплате, премиям, отпускам и.т.д.
Там где я сейчас работаю - уровень людей довольно высокий. И - как обратная сторона медали, одну из которых я только что 
описал выше - люди часто свобОднее в общении. Например в маленьких стартапах, в которых я работал, если кто-то искал
другую работу, могло иногда рассматриваться как чуть ли не предательство. Здесь - ничего подобного...

Поэтому, поговорить с кем-то на рабочую или около-рабочую тему возможностей больше.

Но - уже белее конкретно - хоть уровень людей сравнительно высокий, но программировать большинство практически не умеет, если не считать знания языков программирования и инструментов, что совершенно недостаточно (да и не обязательно, если только работника не нанимают на короткий срок).

Например, попросили меня посмотреть недавно добавленный в одну программу код, который работал медленно, нельзя ли его улучшить, ускорить. Я переписал и ускорил критическую часть в 30 раз. Причем, алгоритм улучшить не удалось - только оптимизация кода и представления данных!

Ощущение у меня, что программированию учить практически перестали - что в США, что в Индии или Китае - большинство людей здесь учились в одной или нескольких из этих стран...
mishafurman: (Default)

Как сглазил: не раз за последнее время рассказывал, что среди самых разных впечетлений о работе в Microsoft
есть одно положительное - сравнительно высокий уровень окружающих сотрудников.
Но, умение писать программы в этот уровень если и входит, то не всегда. В самом деле, это не очень-то
проверяемо при существующей практике интервью.

Пришлось мне недавно делать два code review. О, это было такое! То, что я собираюсь упомянуть - нужно было присвоить
переменной "some_string" типа std::string строку сидящую по пойнтеру p_string_value (типа char * или const char *):

some_string.clear();
std::string temp_string(p_string_value);
some string = temp_string;

Другое у того же автора:

try {<do something> }
catch(...) {}

Видимо идея было сделать программу более надежной - чтобы она не ломалась по причине всяких глупых exceptions :)


mishafurman: (Default)

String wrapper for formatted string output in C++.

 

For a long time I was very reluctant using “ostrstream” that C++ equivalent of the “sprintf” C function because of longer and less understandable code:

 

ostrstream  ss;

ss << “value = “ << x;

string s = ss.str();

 

Three lines and introducing another (besides string) class seems to me too much and inconsistent with my favorite principle of Occam’s razor.

But relatively recently I learned (by reading other’s code) that sometimes this extra complexity can be hidden by using macros. For example, log output macro could be defined:

 

#define LOG(arg) { ostringstrean ss; ss << arg; output(ss.str()); }

 

And can be used:

 

LOG(“sample”);

LOG(“value = “ << x;

 

So, I decided to try implement something similar for just string formatting, without forcing programmer to use any extra classes or variables, something like:

 

String s;

s << “value = “ << x;

// then using s for whatever is needed…

 

Here is the solution: a wrapper around standard string and ostringstream classes:

 //=============================================================================
class String : public std::string
{
public:
   // Constructors
   String() {}
   String(const char * s_) : std::string(s_) {}
   String(std::string const & s_) : std::string(s_) {}
   String(const char * s_, int n_) : std::string(s_, n_) {}
   String(const char * s_, int p_, int n_) : std::string(s_, p_, n_) {}

   // Converting string to character pointer. Defining this operator create some donger of bugs caused
   // dangling pointers, but is very convinient for passing string parameters to "const char *" formal
   // arguments
   operator const char *() { return c_str(); }

   char const & operator [](unsigned long int i_) const { return (*(std::string *)this)[i_]; }
   char const & operator [](unsigned int i_) const { return (*(std::string *)this)[i_]; }
   char const & operator [](int i_) const { return (*(std::string *)this)[i_]; }
   char & operator [](unsigned long int i_) { return (*(std::string *)this)[i_]; }
   char & operator [](unsigned int i_) { return (*(std::string *)this)[i_]; }
   char & operator [](int i_) { return (*(std::string *)this)[i_]; }

   String ToUpper() { String r = *this; for(unsigned int i = 0; i < size(); i++) r[i] = ::toupper(r[i]); return r; }
   String ToLower() { String r = *this; for(unsigned int i = 0; i < size(); i++) r[i] = ::tolower(r[i]); return r; }
};

template<typename T_> String operator *(String const & s_, T_ const & t_)
{
   return s_ + t_;
}

//=============================================================================
class StringStream
{
public:

   struct StringStreamRef
   {
      explicit StringStreamRef(StringStream * ss_) throw() : ss(ss_) {}
      operator StringStream &() const throw()
      {
         return *ss;
      }
      StringStream * ss;
   };

   explicit StringStream(String & str_) : str(&str_)
   {
      ss = new std::ostringstream;
      *ss << *str;
   }
   explicit StringStream(StringStream & ss_) throw()
   {
      *this = ss_;
   }
   StringStream(StringStreamRef ssr_) throw()
   {
      *this = *ssr_.ss;
   }
   StringStream & operator =(StringStream & ss_) throw()
   {
      ss = ss_.ss;
      str = ss_.str;
      ss_.ss = 0;
      ss_.str = 0;
      return *this;
   }
   ~StringStream()
   {
      if(ss && str)
         *str = ss->str();
      delete ss;
   }

   // Operators for converting last calculated string value to String in case "<<" expression is in rhs.  
   operator String() { return ss->str(); }
   template<typename T_> friend StringStream operator <<(StringStream ss_, T_ const & p_);
   template<typename T_> friend StringStream operator <<(String & s_, T_ const & p_);

   operator StringStreamRef() throw()
      {
      return StringStreamRef(this);
      }

private:
   std::ostringstream * ss;
   String * str;

};

template<typename T_> StringStream operator <<(StringStream ss_, T_ const & p_)
{
   *ss_.ss << p_;
   return ss_;
}

template<typename T_> StringStream operator <<(String & s_, T_ const & p_)
{
   StringStream w(s_);
   (*w.ss) << p_;
   return w;
}

 

 

Profile

mishafurman: (Default)
misha furman

October 2019

S M T W T F S
  12345
6789101112
131415161718 19
20 212223242526
2728293031  

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 7th, 2025 05:41 pm
Powered by Dreamwidth Studios