####mautic mautic是一个开源的自动营销平台,好像是目前唯一一个开源的自动营销平台吧,关于自动营销平台之前在学习hubspot的时候简单地提了一下,链接在这里。 简单来说利用mautic你能做的事情就是,监测网站的流量信息,记录下每一个用户的浏览动作,用户在网站登录的邮箱,用户的个人信息,在一个统一的平台上来管理他们,例如你可以给所有注册了你的网站但超过三天没有登录的用户发一封个性化定制的邮件。我理解程度有限不能说的特别深刻,总之mautic应该是目前唯一一个开源的inbound marketing框架了。 mautic文档 mautic是用sympony开发的,部署起来非常简单,我试着把它部署在heroku上,这里不得不提一下heroku的部署实在是太方便了,可以直接设github的resp地址,自动把代码部署上去,代码有更新也会自动更新,国内的云服务就并没有这样方便的功能。 ######contact&segments 简单说一下mautic的几个功能吧,第一个是contact,也就是联系人,我的使用经验来看mautic的联系人是用ip来区分的,事实上当然更复杂一些,还有email merge之类的情况,但是简单来说就是每一个访问的ip对应一个contact,contact的页面访问情况被记录在一个page hit的表里,如果你用过google analytics之类的流量统计工具你一定不会陌生,你需要在你的网站上加一段代码来统计流量信息。 (function(w,d,t,u,n,a,m){w['MauticTrackingObject']=n; w[n]=w[n]||function(){(w[n].q=w[n].q||[]).push(arguments)},a=d.createElement(t), m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m) })(window,document,'script','http(s)://yourmautic.com/mtc.js','mt'); mt('send', 'pageview'); mautic也是这样做的,你可以给contact自定义其它的属性,这些属性可以在contact访问你页面的时候替换上面代码的最后一行来传递给mautic,使用这个功能contact的这个属性必须是publicly updatable的。 contact也可以通过filter进行分组,被分在不同segments里的contact可以在后续进行不同的操作,例如把所有邮箱后缀为gmail的用户分为一组等等。...
####东大人文讲座信息 最近闲着没事刚好又要写人文讲座报告,然而已经不记得当初听过的讲座有哪些了,只能用小猴偷米查到刷卡的时间,刚好想到每次讲座信息校网上都会发一次通知,就顺手用beautifulsoup写了个爬虫爬讲座信息。 # -*- coding: utf-8 -*- import os, sys, time, platform, random import re, json, cookielib # requirements import...
####redissentinel简介 redis sentinel是一种特殊的redis服务器,但仍然是一种redis服务器,在启动过程中,会将运行代码从redis代码替换为sentinel代码。 sentinel的主要作用是在主从环境下,在主redis宕机后,在从redis中选出新的主redis,保证分布式缓存能正常工作。 #####配置文件 主redis:master 从redis: slave 在sentinel的配置中,通过monitor来配置监听哪一个ip port的redis服务器作为master,mymaster只是一个名字 sentinel monitor mymaster 10.171.91.230 6379 2(quorum) 启动后,sentinel会读取配置文件并且将当前的配置保存在一个结构体中,还会通过向该redis发送info信息获取master的状态,同时获取当前的slave以及其他监听此master的sentinel的信息,保存在结构体中并更新sentinel.conf文件,发现新的slave会增加 known-slave 信息,发现新的监听同一master的sentinel会增加know-sentinel信息。 sentinel...
其实刚开始实习的时候我是拒绝的,虽然现在也是早晨9点到晚上6点走很少加班,但是心态和实习刚开始的时候已经很不一样了。 说实话,刚开始实习的时候心里还是很不服的,其实很多组里的代码都没有看懂,也没有深入地去想为什么要这么写,虽然组里的代码不见得是顶尖的代码,但是也不是我现在这个能力能挑出毛病的,我能考虑到的问题实在是太浅太少了。 真的非常感谢我师傅,温总,园哥和组里的其他人,有一个这么懒又很善于机智地偷懒的实习生一定是一件令人苦恼的事情,但是学到的东西真的是很多, 代码结构真的非常重要,设计出一个好的代码结构真的是一件非常难的事情啊,之前看到说代码结构巴拉巴拉的东西都感觉是教科书一样无聊而且老生常谈的东西,说实话确实从来没有放在心上过。。 首先第一步,认真地想一下整个代码的流程是怎么样的,需要实现的功能有哪些,把所有的需求和业务的流程列出来。例如要实现一个分布式环境下访问redis读写数据的功能。肯定需要建立与redis的连接,需要管理与redis的连接,redis的连接要执行redis的命令,需要封装好跟业务相关的接口给别人,等等,这些说起来很简单,但是其实自己之前写代码的时候遇到这种自以为已经明白的需求的时候是没有仔细去想要怎么写的,心里想的就是,不就是一个redis连接池管理,提供一些对外的接口吗,其实是没有仔细想一想就开始动手写代码的,其实这种问题虽然通用,但是对每个业务场景其实都是有细节上的设计区别的,仔细地想过,才能写出最符合这个场景的代码。 第二步,想好内部的类应该怎样来设计,把功能剥离出来,把需求映射到具体的类上来负责,每个内部的类都是有自己明确的责任和要做的事情的,对每个类的函数都要仔细地想,为什么要提供这个函数,返回值类型,参数类型,出参还是返回值,这个函数这样实现是不是能够很好地符合我想用它做的事情,重复的代码能不能通过再提取函数或者模板之类的方法简化,整个类的设计能不能很好地扩展,整个类每一部分分工是不是明确的。都是值得认真考虑的问题,不能一拍脑袋觉得自己需要获取某个东西或者处理什么东西就加个函数,函数的形式也不认真想。另外,提供给外部的接口是什么样子的,也要和别人讨论好。 第三步,函数内部实现和各种异常的考虑,异常处理是非常非常重要而且要考虑很久的,每个地方可能会发生什么样的异常,处理异常经常会见到if else以及各种嵌套的if else结构,各个分支要处理的情况要想好。函数内部的实现逻辑要清楚,什么时候该做什么样的事情,多线程访问的地方锁的控制,异常的时候锁的处理,获取到的变量里面值究竟会有哪些情况,主要还是异常情况的考虑,这个真的是取决于对自己要写的东西的了解程度和经验了。 第四步,把代码整合起来的时候,好的代码结构整合起来就像汽车人变形一样,各个部分严丝合缝地组合在一起,然而不好的代码,比如我之前写的一些代码。。。就像整理一团很乱的电线一样,从这团里抽出一根,再从另一团里抽出一根,再接到一起,扭在一起也不知道谁是谁了。。。 写的代码还是太少了,代码经验对于写代码来说真的还是很重要的,有些事情如果没有有经验地人提醒的话,真的只有撞墙了才能感觉到。其实自己说的还是给人一种老生常谈的很傻的感觉,但是这方面的体会印象真的很深。真的非常感谢大家。
#####Map Reduce join 课程首先给出了一个关于join的例子,首先是文件的内容 testfile1 able,991 about,11 burger,15 actor,22 testfile2 Jan-01 able,5 Feb-02 about,3 Mar-03 about,8 Apr-04 able,13 Feb-22 actor,3...
object pool object pool pattern 项目里需要用到redis,同时也要有redis的连接池之类的东西,在github上找到了一个连接池(https://github.com/luca3m/redis3m),就是普通的连接池设计思想。 Pool里用一个set成员变量保存所有的连接,当调用getconnection成员方法的时候就在连接池里查找,如果有可用的连接,就获取返回该连接,并且从set中去掉该连接,当client使用完毕以后,再用put成员方法将connection put回连接池里,我觉得唯一需要修改的就是连接池没有最大连接数的限制。我已经pull request了,这也是我人生中第一个被不认识的人接受的request。。。 但是在看组里数据库的连接池的代码时,却发现组里的连接池并不是正常的连接池做法。 connection是连接类 此外还有一个connectionobj的类,成员变量一个读写锁和connection的指针,connectionobj提供getconnection和releaseconnection方法,getconnection方法中首先加锁,然后将成员变量connection的指针返回,releaseconnection方法中释放掉getconnection中加的锁。 connection_pool是连接池。管理的是connectionobj的指针。包括最大连接数,一个vector<connectionobj*> 的成员变量,一个int整数conn_pos记录当前connectionpool位置,getconnectionobj,releaseconnectionobj成员方法,连接池初始化时就创建所有连接。 getconnection方法有一个connpos的出参,方法中首先中加锁,然后用conn_pos++%poolsize来求出下一个连接的位置,调用下一个连接的getconnectionobj方法,releaseconnection方法要使用getconnection获得的connpos做入参,然后调用对应connectionobj的release方法。 说的不太清楚,假如说现在连接池的大小是3,connectionobj obj1 obj2 obj3,1号线程get,获取到了obj1,未使用完,则conn_pos++%poolsize为1. 2号线程get...
####MapReduce 通过coursera课上一个hadoop最基本的例子来看mapreduce,统计单词出现的次数。 我们在hdfs上放置了两个文件,testfile1和testfile2 testfile1: A long time ago in a galaxy far far away testfile2: Another episode of Star Wars...
实习已经过去四个月了,也是时候反思一下自己在实习过程里的收获了。 #####编程规范 首先就是编程规范的问题,对比较大的项目来说,编程规范确实很重要,其实对于普通的,不是为了防护异常的编程规范问题来说,主要是为了方便进行维护和别人写作,如果代码都是自己写的,各种异常又考虑到了,其实也无所谓。 但是能一个人写大项目的人毕竟还是太少了,总是要和别人一起协作来写代码。所以编程规范还是要学习的,其实注意编程规范除了方便维护扩展以外,最重要地还是看起来清楚,就容易减少遗漏的异常,能够更方便地进行异常防护。 #####深入思考 以前考虑问题还是不够全面,实习以后发现其实很多看起来很简单的问题仔细想一想都有很多没有注意到的点啊,项目组即使很小的问题都会几个人在白板上进行很详细的讨论,虽然感觉有些讨论没有意义,但是讨论过后还是会把大部分问题给考虑全面。 #####一些技能 另一种物联网:我之前对物联网的概念局限在智能家居这种个人场景的应用上,没有想到做这种为企业来提供解决方案的物联网应用,实习期间也对这种物联网的应用场景,设计,架构什么的学习了很多。感觉这一类物联网项目,差不多就是底层有大量的设备,设备通过各种形式各种协议进行通信,顶层是用来进行管理的系统,管理系统和底层设备之间会有其他几层用来处理并发,调度给设备安排任务,缓存,负载均衡,底层偏上还会有协议的适配等等。 STtester:用来做python测试。修改了一个项目组内的multi thread pyunit 测试框架。 pyunit website OracleDBtester: pl/sql是一种ORACLE提供的可执行程序语言,可以用来写一些ORACLE的测试脚本之类的。 用pl/sql封装了一些操作(很少)用来做组内的数据库测试。这个东西写起来也是困难。 pl/sql examples Python...
#####QT字符串 当QString和std::string互相转换时,容易出现很多问题 Convert QString to string QString是使用utf-16编码的,但是std::string可能会是很多其他不同的编码格式。string自身并没有编码格式的概念,但是string里byte的来源会有很多种不同的编码格式。 我们常常使用的QString函数包括toUtf8,fromUtf8,toLocal8bit,fromLocal8bit,toStdString,fromStdString。 首先是编码格式的问题coding,unicode并不是一种特定的编码格式,而是一个标准,在不同的地方unicode编码可能对应不同的编码格式,通常是utf-16,大家通常区分的utf-8和unicode实际上是utf-16和utf-8的竞争utf-16&utf-8 你的计算机上可能会有ascii,utf-8,local8bit(就是你本地的编码格式,同样是8位,但是并不是统一的unicode编码格式),utf-16等等编码格式,要想保证QString的工作正常,最好的方法自然是保证QString的来源和输出都是使用了正确地对应的to,from方法,tostdstring和fromstdstring都是使用的ascii方法。但是如果你不知道自己的string来源是什么样的编码格式,那么也没有办法保证你的QString是正常工作的。 QT国际化,QString的出现是为了满足QT跨平台跨地域的需要,因此使用了utf的编码格式,无论是从文件中读取还是其他方式获取的byte,都尽量使用QT的方法来处理(使用QT的文件流,QT的http方法),这样可以保证你的byte不会被莫名其妙地改变某些东西。 #####QT信号&槽 signal&slot QT的slot和signal类似于callback,当对象状态发生改变时,可以释放自己定义的signal,然后由对应的slot进行处理 #include <QObject> class Counter : public...
####定时发送http请求 import sched, time import httplib,sys #from tester.models import Tasks class planrequest: planner = sched.scheduler(time.time, time.sleep) plannum = 1 planinterval...
#####Problems and Models: machine learning是指通过对一系列含有n个feature,已知具有某种attribute的变量(训练集)进行分析,找到一个hypothesis(或者叫function,model,pattern,就是找到一个模型或者假设),这个hypothesis接受到一个变量的n个feature后能够分析出这个变量该attribute的值。 比如输入一系列面积为x,价格为y的房屋信息,找出一个hypothesis,向这个hypothesis输入一个X,这个hypothesis就会预测x=X时,y应该是多少。 input: feature:x1,x2,x3 = 200,300,150,… attribute:y1,y2,y3 = 10000,20000,15000,… hypothesis: h(x):h(X)=Y,h(400) = 25000,… 这里输入数据只含有一个feature:x,我们要预测的就是y。 我们最终的目的是让h(x)预测的结果和实际的y值相差最小,也就是 minimize(h(x)-y)...
一直对http的headers不是特别清楚,推荐两篇博客。 head http 个人感觉headers的主要作用就是传递通信中客户端浏览器,请求页面,服务器的相关的信息,同时可以对传递的内容进行格式的约束和合法性的判断。一些数据服务也用headers来做授权验证。 比如apicloud提供了数据云服务,可以通过rest api访问数据库,如果需要查询某个应用的数据库的话,就需要将应用id和key值以及一个数字用sha1加密,存储在headers的某一名字中,然后再发起http请求,服务器在验证headers中该名字的值是否合法,验证合法过后返回查询结果。 Apache有两个http的jar包,httpcomponent这个包里的httpclient不同于commons里的httpclient是一个可实例的类,Httpcomponents中的httpclient(org.apahce.http.client.HttpClient)是一个接口,CloseableHttpClient是继承了这个接口的抽象类,因此要使用httpclient有两种方法。 一种是继承httpclient这个接口,另一种就是使用提供的工厂类,工厂类可以更灵活的获取抽象类的实例,而HttpClients就是一个这样的一个类,它里面有很多静态方法实现抽象类CloseableHttpClient的实例。 HttpClient client = HttpClients.createDefault(); HttpClient client = HttpClients.createMinimal(); 提供的method(GET,POST,HEAD)都可以调用addheader或者setheader的方法来添加header。这两个函数的不同点在于: addHeader,如果同名header已存在,则追加至原同名header后面;setHeader,如果同名header已存在,则覆盖一个同名header。 同名Header可以有多个值,但是运行时使用的是第一个值(这个不太清楚,还需要多测试几次)。 HttpGet...
###选择题 答选择题只有一个感受,数学不好抱憾终生= =,选择题差不多三分之一是数学方面,概率,排列组合之类的题目,三分之一的C++基础知识,三分之一的数据结构和算法,比如红黑树、二叉树。 ###简答题 简答题有三道。感觉都是比较实际的问题 #####Freelist 第一道题大概是为了避免频繁的new/delete操作,实现一个freelist,管理定长的内存块,当需要内存时从freelist中申请,当归还内存时不直接归还给OS,而是归还到freelist中,要求考虑多线程的问题,并且不能使用stl。 #####Answer 我的做法是用数组保存内存块,至于多线程的问题就是用的最简单的加锁。 #####用户配额 第二题是一个对不同优先级的用户给予不同配额的题目,比如对A用户20%,B用户40%,C用户40%,那当有总共有100个请求的时候就需要按比例来给用户处理,但如果只有一个用户的请求时就要100%的处理那个用户d请求。 #####Answer 生成一个随机数,通过判断随机数所在的范围来选择相应哪一个用户的请求。 #####响应序列 第三题是输入一串序列,如1324765。 输出1 23 4 567 就是如果低优先级的请求先到的话,不立即响应,等到比它优先级高的都输出了才将他输出,并且要求写出。...